พฤติกรรมเริ่มต้นของ“ git push” โดยไม่ระบุสาขา


1366

ฉันใช้คำสั่งต่อไปนี้เพื่อผลักดันไปยังสาขาระยะไกลของฉัน:

git push origin sandbox

ถ้าฉันพูด

git push origin

ผลักดันการเปลี่ยนแปลงในสาขาอื่นของฉันด้วยหรือจะอัพเดทเฉพาะสาขาปัจจุบันของฉัน ฉันมีสามสาขาmaster, และproductionsandbox

git pushเอกสารไม่ได้ชัดเจนมากเกี่ยวกับเรื่องนี้ดังนั้นผมอยากจะชี้แจงนี้ให้ดี

git pushคำสั่งต่อไปนี้อัพเดตทุกสาขาและรีโมทใด

git push 
git push origin

origin ด้านบนเป็นรีโมท

ฉันเข้าใจว่าgit push [remote] [branch]จะดันเฉพาะสาขานั้นไปยังระยะไกล


เกี่ยวกับการกำหนดค่าของเครื่องมือ diff โดยทั่วไปและสคริปต์ git difftool ใหม่ฉันได้เพิ่มคำตอบใหม่ในคำถาม SO อื่น ๆ นี้: stackoverflow.com/questions/255202/…
VonC

67
ฉันโพสต์บล็อกเกี่ยวกับพฤติกรรมที่น่าประหลาดใจgit pushซึ่งอาจเป็นที่สนใจ
Mark Longair

1
@ Mark: ในงานอื่น ๆ ผลักเฉพาะสาขาปัจจุบันไปยัง upstream ที่ถูกติดตาม ดี
VonC


help.github.com/articles/pushing-to-a-remoteวางลิงค์นี้ไว้ที่นี่เพื่อรับความช่วยเหลือจากมือใหม่อย่างฉัน
MycrofD

คำตอบ:


1591

คุณสามารถควบคุมพฤติกรรมเริ่มต้นโดยการตั้งค่า push.default ในการกำหนดค่า git ของคุณ จากเอกสาร git-config (1) :

push.default

กำหนด action git push ที่ควรทำหากไม่มีการกำหนด refspec ในบรรทัดคำสั่งไม่มีการกำหนด refspec ในระยะไกลและไม่มีการอ้างอิง refspec โดยตัวเลือกใด ๆ ที่ให้ไว้ในบรรทัดคำสั่ง ค่าที่เป็นไปได้คือ:

  • nothing: อย่าผลักดันอะไร

  • matching: กดสาขาที่ตรงกันทั้งหมด

    สาขาทั้งหมดที่มีชื่อเหมือนกันในปลายทั้งสองจะถือว่าเป็นการจับคู่

    สิ่งนี้เคยเป็นค่าเริ่มต้น แต่ไม่ใช่ตั้งแต่ Git 2.0 ( simpleเป็นค่าเริ่มต้นใหม่)

  • upstream: ผลักสาขาปัจจุบันไปที่สาขาต้นน้ำ ( trackingเป็นคำพ้องความหมายที่เลิกใช้สำหรับอัปสตรีม)

  • current: ดันสาขาปัจจุบันไปยังสาขาที่มีชื่อเดียวกัน

  • simple: (ใหม่ใน Git 1.7.11) เหมือนต้นน้ำ แต่ปฏิเสธที่จะผลักดันถ้าชื่อของสาขาต้นน้ำแตกต่างจากท้องถิ่น

    นี่เป็นตัวเลือกที่ปลอดภัยที่สุดและเหมาะสำหรับผู้เริ่มต้น

    โหมดนี้เป็นค่าเริ่มต้นใน Git 2.0

โหมดที่เรียบง่ายกระแสและอัปสตรีมเหมาะสำหรับผู้ที่ต้องการผลักดันสาขาเดียวหลังจากเสร็จงานแม้ในขณะที่สาขาอื่นยังไม่พร้อมที่จะถูกผลักออก

ตัวอย่างบรรทัดคำสั่ง:

วิธีดูการกำหนดค่าปัจจุบัน:

git config --global push.default

วิธีตั้งค่าการกำหนดค่าใหม่:

git config --global push.default current

11
อาจเป็นเรื่องน่าสังเกตว่านี่เป็นของใหม่ใน v1.6.3: kernel.org/pub/software/scm/git/docs/RelNotes-1.6.3.txt
CB Bailey

8
"push.default" นี้เป็นสิ่งที่ยิ่งใหญ่ที่สุดสำหรับการทำงานกับ repos หลาย ๆ ตัว ตั้งค่าเป็น "การติดตาม" และคุณก็ทำได้ดี รวมกับสาขา - ตั้งค่าอัปสตรีมทำให้การกดและดึงสะดวกยิ่งขึ้น
jpswain

13
"การติดตาม" เป็นคำพ้องที่เลิกใช้แล้วสำหรับ "อัปสตรีม
LuckyMalaka

22
มันน่าสังเกตว่าตั้งแต่ Git 1.7.11 มีsimpleโหมดใหม่ โหมดนี้มีวัตถุประสงค์เพื่อให้เป็นค่าเริ่มต้นในอนาคต simpleทำงานเหมือนupstreamแต่ต้องการcurrentให้ชื่อสาขาเหมือนกันทั้งสองด้าน
ไก่

9
เป็นที่น่าสังเกตว่าในฐานะของ Git 2.0 simpleพฤติกรรมในขณะนี้จึงเป็นค่าเริ่มต้น
do0g

209

คุณสามารถตั้งค่าพฤติกรรมเริ่มต้นสำหรับคอมไพล์ของคุณด้วย push.default

git config push.default current

หรือถ้าคุณมีที่เก็บข้อมูลจำนวนมากและต้องการสิ่งเดียวกันทั้งหมด

git config --global push.default current

ปัจจุบันในการตั้งค่าที่นี้หมายถึงว่าโดยปกติคุณจะเพียงผลักดันสาขาในปัจจุบันเมื่อคุณทำผลักดันคอมไพล์

ตัวเลือกอื่น ๆ :

  • ไม่มีอะไร: อย่าผลักอะไรเลย
  • การจับคู่: กดกิ่งไม้ที่ตรงกันทั้งหมด (ค่าเริ่มต้น)
  • การติดตาม: ผลักสาขาปัจจุบันไปยังสิ่งที่มันกำลังติดตาม
  • ปัจจุบัน: กดสาขาปัจจุบัน

อัปเดต - วิธีใหม่ในการทำเช่นนี้

ในฐานะของ Git 1.7.11 ให้ทำสิ่งต่อไปนี้:

git config --global push.default simple

นี่คือการตั้งค่าใหม่ที่นำมาใช้ซึ่งทำงานในลักษณะเดียวกับกระแสและจะใช้ค่าเริ่มต้นเป็น git จาก v 2.0 ตามข่าวลือ


29
ใช่ฉันอ่านคำตอบที่คุณอ้างถึง แต่คำตอบนั้นบอกเพียงว่าจะต้องทำอย่างไรและไม่ใช่ว่าจะทำอย่างไร ดังนั้นฉันจึงเพิ่มคำตอบเพื่อให้ข้อมูลทั้งหมดที่จำเป็นในการตั้งค่านั้นอยู่ในหน้าเดียวกัน
Christoffer

3
ตกลง; มันจะดีกว่าที่จะแนะนำการแก้ไขโพสต์ดังกล่าวเพราะไม่มีใครจะเห็นคำตอบของคุณเพราะมันไม่น่าจะได้รับการโหวตมาก
CharlesB

คนเราจะไปดึงสาขาปัจจุบันอย่างไร ดึงต้นกำเนิดคอมไพล์?
Francois

200

git push originจะผลักดันการเปลี่ยนแปลงทั้งหมดในสาขาท้องถิ่นที่มีการจับคู่สาขาระยะไกลที่originเป็นสำหรับgit push

ทำงานเหมือนgit push <remote>อยู่ที่ไหนซึ่ง<remote>เป็นสาขาระยะไกลในปัจจุบัน (หรือที่มาหากไม่มีการกำหนดค่าระยะไกลสำหรับสาขาปัจจุบัน)

จากส่วนตัวอย่างของgit-pushหน้าคน


2
ใช่นั่นทำให้ชัดเจน ฉันอาจใช้ git รุ่นเก่ากว่า (1.6.1.1 Mac OS X) ซึ่งไม่มีตัวอย่างเหล่านี้ในหน้า man
PlagueHammer

อาจเป็นไปได้ว่าฉันใช้ 1.6.3.1 ฉันหามันได้จากเว็บไซต์ที่ฉันเชื่อมโยง
baudtack

2
ดังนั้นในกรณีของฉันที่ทุกสาขาในท้องถิ่นมี "ต้นกำเนิด" ระยะไกลเดียวกัน "git push" จะเหมือนกันกับ "ต้นกำเนิด git push" ซึ่งจะผลักเฉพาะสาขาท้องถิ่นที่มีสาขาตรงกันในระยะไกล
PlagueHammer

@Debajit ใช่! เป็นคำถามที่ดีมาก ฉันคิดเสมอว่าการใช้ git push นั้นจะผลักสาขาปัจจุบันเท่านั้น ชัดเจนว่าไม่! ดีมากที่จะรู้
baudtack

5
คำถามนี้เก่า แต่สำหรับใครใหม่ @docgnome นั้นถูกต้อง เพียงแค่เรียกใช้ 'ต้นกำเนิด push git' จะผลักดันทุกสาขาแทนเฉพาะสาขาปัจจุบัน ใช้ 'git push -f -v -n origin development' เพื่อบังคับให้พุชชื่อการพัฒนา ใช้แฟล็ก -n เพื่อจำลองผลลัพธ์การกด git เพื่อให้คุณเห็นล่วงหน้าว่าสาขาใดจะได้รับผลกระทบ หากดูดีแล้วให้เรียกใช้ 'git push -f -v development development' นี่อาจเป็นประโยชน์stackoverflow.com/questions/3741136/git-push-f-vs
Dylan Valade

54

ฉันแค่มุ่งมั่นรหัสของฉันไปที่สาขาและผลักดันให้ GitHub เช่นนี้

git branch SimonLowMemoryExperiments
git checkout SimonLowMemoryExperiments
git add .
git commit -a -m "Lots of experimentation with identifying the memory problems"
git push origin SimonLowMemoryExperiments

3
คุณสามารถรวมการกระทำเพื่อ `git กระทำ -am" ... "`
James Harrington

17
คำตอบนี้เกี่ยวข้องกับคำถามหรือไม่? :?
Asim KT

26

นี่คือข้อมูลที่มีประโยชน์และเป็นประโยชน์เกี่ยวกับGit Push : Git Push: เพียงแค่คำแนะนำ

การใช้ git push ที่พบมากที่สุดคือการผลักดันการเปลี่ยนแปลงในพื้นที่ของคุณไปยังที่เก็บข้อมูลต้นน้ำสาธารณะของคุณ สมมติว่า upstream เป็นรีโมตที่ชื่อ "origin" (ชื่อรีโมตดีฟอลต์หากที่เก็บของคุณเป็นโคลน) และสาขาที่จะอัพเดตเป็น / จากนั้นมีชื่อว่า "master" (ชื่อสาขาดีฟอลต์) ซึ่งทำด้วย:git push origin master

git push origin จะผลักดันการเปลี่ยนแปลงจากสาขาท้องถิ่นทั้งหมดไปยังสาขาที่ตรงกันกับรีโมทต้นทาง

git push origin master จะผลักดันการเปลี่ยนแปลงจากสาขาต้นแบบท้องถิ่นไปยังสาขาต้นแบบระยะไกล

git push origin master:staging จะผลักดันการเปลี่ยนแปลงจากสาขาหลักในเครื่องไปยังสาขาการจัดเตรียมระยะไกลหากมีอยู่


git push origin branch_nameด้วยเหตุผลบางอย่างผลักดันไม่เพียง แต่branch_nameสาขา แต่ยังสาขาอื่น ๆ ในพื้นที่ของฉัน (รุ่น git 1.9.1)
mrgloom

git push origin master:stagingเป็นอัญมณีที่ซ่อนเร้น!
Shakeel

19

(มีนาคม 2012)
ระวัง: matchingนโยบายเริ่มต้นนั้นอาจเปลี่ยนแปลงเร็ว ๆ นี้
(บางครั้งหลังจาก git1.7.10 +)
:

โปรดดูที่ " กรุณาหารือเกี่ยวกับสิ่งที่ 'ดันคอมไพล์' ควรจะทำอย่างไรเมื่อคุณไม่ได้พูดในสิ่งที่จะผลักดัน? "

ในการตั้งค่าปัจจุบัน (คือpush.default=matching) โดยไม่โต้แย้งจะผลักดันทุกสาขาที่มีอยู่ทั้งในประเทศและจากระยะไกลที่มีชื่อเดียวกันgit push
โดยปกติจะเป็นสิ่งที่เหมาะสมเมื่อผู้พัฒนาผลักดันไปยังที่เก็บสาธารณะของเขา แต่อาจสร้างความสับสนหากไม่เป็นอันตรายเมื่อใช้ที่เก็บที่แชร์

ข้อเสนอคือการเปลี่ยนค่าเริ่มต้นเป็น ' upstream'เช่นกดเฉพาะสาขาปัจจุบันและผลักไปที่ดึง git สาขาจะดึงจาก
ผู้สมัครคนอื่นคือ 'current '; สิ่งนี้จะผลักดันเฉพาะสาขาปัจจุบันไปยังสาขาระยะไกลที่มีชื่อเดียวกัน

สิ่งที่ถูกกล่าวถึงจนถึงสามารถเห็นได้ในหัวข้อนี้

http://thread.gmane.org/gmane.comp.version-control.git/192547/focus=192694

การสนทนาที่เกี่ยวข้องก่อนหน้านี้รวมถึง:

หากต้องการเข้าร่วมการสนทนาให้ส่งข้อความของคุณไปที่: git@vger.kernel.org


18

ฉันเพียงแค่ใส่สิ่งนี้ในส่วน. gitconfig aliases ของฉันและชอบวิธีการทำงาน:

pub = "!f() { git push -u ${1:-origin} `git symbolic-ref HEAD`; }; f"

จะผลักดันสาขาในปัจจุบันที่มาด้วยgit pubหรือ repo git pub repo-nameอีกด้วย รสอร่อย


4
นั่นเป็นสิ่งที่ดี แต่น่าเสียดายที่สมมติว่าสาขามีชื่อเดียวกันกับที่เก็บอื่น ลองgit push -u --repo="origin" $1;แทน มันทำงานได้ค่อนข้างดียกเว้นถ้าคุณกดไปที่ที่เก็บอื่นชื่อสาขาจะเป็นชื่อที่ใช้โดยที่เก็บอื่น ๆ ไม่ใช่ชื่อที่คุณกำลังกดจาก
Casebash

เฮ้ขอบคุณ! ทำให้ฉันต้องการรุ่นที่สมบูรณ์ยิ่งขึ้นที่ตรวจสอบสถานะการติดตามก่อนกด แต่ฉันจะติดกับฉันตอนนี้เพราะฉันไม่ค่อยมีชื่อสาขาที่แตกต่างกันระหว่าง repos
Mat Schaffer


8

การพุชแบบคอมไพล์จะพยายามและส่งสาขาไปยังเซิร์ฟเวอร์ระยะไกลทั้งหมดนี่เป็นสิ่งที่คุณไม่ต้องการ ฉันมีการติดตั้งสองสามอย่างเพื่อจัดการกับสิ่งนี้:

นามแฝง "gpull" และ "gpush" อย่างเหมาะสม:

ใน ~ / .bash_profile ของฉัน

get_git_branch() {
  echo `git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/'`
}
alias gpull='git pull origin `get_git_branch`'
alias gpush='git push origin `get_git_branch`'

ดังนั้นการดำเนินการ "gpush" หรือ "gpull" จะผลักดันเฉพาะสาขา "ปัจจุบัน" ของฉัน


3
หากคุณต้องการพฤติกรรมของ gpush คุณสามารถตั้งค่า remote.origin.push = HEAD (เช่น "git config remote.origin.push HEAD") ตามที่กล่าวไว้ในส่วนตัวอย่างของหน้า man-git-push
Trevor Robinson

5
ไม่จำเป็นถ้าคุณดูที่โพสต์ข้างต้นโดย "Brian L"
jpswain

1
มันเป็นเพราะไม่มี equv สำหรับ pull pull.default
SamGoody

8

คุณสามารถเปลี่ยนพฤติกรรมเริ่มต้นใน.gitconfigตัวอย่างเช่น:

[push]
  default = current

ในการตรวจสอบการตั้งค่าปัจจุบันให้รัน:

git config --global --get push.default

3

แทนที่จะใช้นามแฝงฉันชอบสร้างสคริปต์ git-XXX เพื่อให้ฉันสามารถควบคุมแหล่งข้อมูลเหล่านั้นได้ง่ายขึ้น (devs ของเราทุกคนมีแหล่งที่มาควบคุมบางอย่างบนเส้นทางของสิ่งเหล่านี้)

สคริปต์นี้ (เรียกว่าgit-setpush) จะตั้งค่ากำหนดค่าสำหรับremote.origin.pushสิ่งที่จะผลักสาขาปัจจุบันเท่านั้น:

#!/bin/bash -eu

CURRENT_BRANCH=$(git branch | grep '^\*' | cut -d" " -f2)
NEW_PUSH_REF=HEAD:refs/for/$CURRENT_BRANCH

echo "setting remote.origin.push to $NEW_PUSH_REF"
git config remote.origin.push $NEW_PUSH_REF

ทราบว่าในขณะที่เรากำลังใช้Gerritงานมันจะกำหนดเป้าหมายเป็นrefs/for/XXXจะผลักดันเข้าไปในสาขาการตรวจสอบ มันยังถือว่ากำเนิดเป็นชื่อระยะไกลของคุณ

เรียกใช้หลังจากเช็คเอาต์สาขาด้วย

git checkout your-branch
git setpush

เห็นได้ชัดว่าสามารถปรับเปลี่ยนเพื่อทำการเช็คเอาต์ได้ แต่ฉันชอบสคริปต์ที่จะทำสิ่งหนึ่งและทำได้ดี


ความคิดที่ดีการตั้งค่า remote.origin.push สำหรับการใช้ gerrit สาขาคุณลักษณะในท้องถิ่นของฉันfeature/fix_fubarทั้งหมดชี้ไปที่สาขาต้นน้ำทั่วไปเช่นmasterหรือdevelopดังนั้นนี่จะชี้ไปที่ต้นน้ำผิด โฟลว์ท้องถิ่นของคุณมีลักษณะอย่างไรสำหรับ repos ที่ควบคุมโดย gerrit?
spazm

หากคุณมีเพียงหนึ่ง "เป้าหมาย" สาขา Gerrit git config remote.origin.push HEAD:refs/for/masterลองเพียง
fracz

2

ฉันได้เพิ่มฟังก์ชั่นต่อไปนี้ลงในไฟล์. bashrc ของฉันเพื่อทำงานเหล่านี้โดยอัตโนมัติ มันใช้ git push / git pull + ชื่อของสาขาปัจจุบัน

function gpush()
{
  if [[ "x$1" == "x-h" ]]; then
    cat <<EOF
Usage: gpush
git: for current branch: push changes to remote branch;
EOF
  else
    set -x
    local bname=`git rev-parse --abbrev-ref --symbolic-full-name @{u} | sed -e "s#/# #"`
    git push ${bname}
    set +x
  fi
}

function gpull()
{
  if [[ "x$1" == "x-h" ]]; then
    cat <<EOF
Usage: gpull
git: for current branch: pull changes from
EOF
  else
    set -x
    local bname=`git rev-parse --abbrev-ref --symbolic-full-name @{u} | sed -e "s#/# #"`
    git pull ${bname}
    set +x
  fi
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.