วิธีผสานสาขาปัจจุบันเข้ากับสาขาอื่น


182

ฉันมีสองสาขาหลักและ dev ฉันทำงานกับ dev เสมอและตรวจสอบรหัสในสาขาหลักเมื่อได้รับการอนุมัติสำหรับการใช้งานจริง เมื่อฉันทำฉันต้องทำสิ่งต่อไปนี้:

git checkout master
git merge dev
git checkout dev

นั่น verbose อย่างสุดขีดและเนื่องจากฉันทำมันบ่อยครั้งฉันต้องการที่จะลด มีคำสั่ง git ใดคำสั่งเดียวที่ฉันสามารถใช้เพื่อผสานจาก dev สาขาปัจจุบันของฉันไปยัง master branch อื่น ๆ โดยไม่ต้องเช็กเอากิ่ง master ก่อนหรือไม่? บางสิ่งที่อาจจะชอบ:

git merge dev to master

จะน่ากลัว ฉันดูเอกสารคอมไพล์และไม่เห็นอะไรเลย


1
คุณลองใช้ git push แล้วหรือยัง?
Jay Sullivan

11
คำแนะนำในการผลักคืออะไร ใช้สำหรับอัปเดตรีโมตไม่ใช่การรวมภายในที่เก็บข้อมูลของตัวเอง
Cascabel

4
Jefromi ถูกต้องการกดไม่มีประโยชน์ที่นี่ ฉันกำลังพูดถึงสาขาท้องถิ่นอื่นไม่ใช่สาขาระยะไกล
Chris

2
แม้เลวคือเมื่อคุณมีการเปลี่ยนแปลงในท้องถิ่นปราศจากข้อผูกมัด: git stash, git checkout master, git merge dev, ,git checkout dev git stash pop
Mu Mind

2
เป็นคำถามที่ดี ฉันต้องการสิ่งนี้เช่นกันเพราะฉันต้องการดึงเข้าไปในสาขาที่ไม่หมุนเวียน ฉันต้องการหลีกเลี่ยงการสลับแบรนช์เพราะฉันมีกระบวนการที่เริ่มต้นการบิลด์หากไฟล์ใด ๆ ในแผนผังการทำงานเปลี่ยนไป
เคลวิน

คำตอบ:


94

1.เพิ่มชื่อแทนระยะไกลสำหรับที่เก็บในเครื่องของคุณเช่น:

git remote add self file:///path/to/your/repository

(หรือบน windows git remote add self C:\path\to\your\repository)

2.กดไปที่รีโมทด้วยตนเองเช่น:

git push self dev:master

2
submodules! สิ่งนี้ไม่เพียงแก้ปัญหาของคำถามที่ถาม แต่ยังช่วยแก้ปัญหาการสลับสาขาเมื่อมีเพียง submodule สุดยอดเคล็ดลับ!
eddiemoya

2
+1 นี่คือความคิดสร้างสรรค์และไม่แตะต้องต้นไม้ที่ทำงานเลย เพียงแค่การชี้แจง: /path/to/your/repositoryเป็นเส้นทางไปยังต้นไม้ทำงานของคุณคือไม่รวม.gitไดเรกทอรี นอกจากนี้ควรดำเนินการต่อโดยไม่บอกว่า: รีโมตจะต้องได้รับการอัพเดตหากคุณย้าย repo
เคลวิน

ฉันไม่มีโชคใด ๆ ที่ได้รับสิ่งนี้เพื่อทำงานใน windows ... git remote add self file:///c/projectsเพิ่งกลับมาพร้อมกับบันทึกการใช้งาน
Maslow

2
@ JosephK.Strauss คุณต้นแบบผสานครั้งแรกในสาขาปัจจุบัน (สามารถdev) git push self dev:masterแล้วดันผสานกระทำโดยใช้
Leonid Shvechikov

4
ทำไมชื่อแทนระยะไกล ทำงานได้ดีสำหรับฉัน:. git push . head:master
geon

60

คำตอบที่ได้รับการโหวตสูงสุดในปัจจุบันโดย @zerome เป็นคำตอบที่ดี แต่ค่อนข้างละเอียดโดยไม่จำเป็น

ในฐานของ repo git ของคุณคุณสามารถทำได้: git push . dev:master

วิธีการแก้ปัญหาทั่วไปที่จะทำงานได้ทุกที่ในต้นไม้จะเป็น:

git push $(git rev-parse --show-toplevel) dev:master

3
git push . dev:masterทำให้ชีวิตฉันง่ายขึ้นมาก! คำตอบที่ดีที่สุดโดยไกลขอบคุณ
เจเรมีเบโลโล

คุณกำลังจะผลักต้นแบบที่ผสานไปยังที่เก็บข้อมูลระยะไกลอย่าง Github หรือไม่? บันทึกขั้นตอนโดยการทำgit push origin dev:master
Alex R

1
เป็นไปได้ไหมที่จะทำซ้ำmerge --no-ffพฤติกรรมด้วยสิ่งนี้?
exhuma

1
ฉันได้รับชื่อรีโมตไม่ถูกต้อง "" ใน Windows ฉันยังต้องทำอีกgit remote add self file:///myRepoหรือไม่?
kiewic

1
แต่นี่ไม่ใช่การผสานจริง ๆ ... มันจะได้ผลถ้า dev อยู่ก่อนหน้าของเจ้านาย แต่ถ้ามันไม่ใช่ล่ะ
Thomas Levesque

44

ทางออกที่ดีที่สุดของคุณคือการใช้นามแฝงที่วางไว้ใน gitconfig ทั่วโลกของคุณ ( ~/.gitconfig):

[alias]
    merge-to = "!f() { git checkout $1 && git merge $2 && git checkout -; }; f"

เพื่อให้คุณสามารถเรียกใช้ได้จากที่เก็บใด ๆ เช่น

git merge-to master dev

3
จะเกิดอะไรขึ้นถ้าการผสานไม่อัตโนมัติ แต่ต้องมีการแก้ไขผสาน (ในกรณีนี้ฉันคิดว่าไม่มีงานทำกับอาจารย์ดังนั้นมันจะไม่เกิดขึ้น แต่ยัง)
Stein G. Strindhaug

@Stein: เนื่องจากฉันใช้&&ไม่;มันจะล้มเหลวในการรวมและไม่พยายามเปลี่ยนกลับ หวังว่าผู้ใช้จะฉลาดพอที่จะเห็นข้อความ "ผสานล้มเหลว" และจัดการกับมัน
Cascabel

6
ฉันชอบmerge-to = "!f() { export tmp_branch=สาขา git นี้ grep '*' | tr -d '*' ; git checkout $1 && echo git merge $tmp_branch && echo git checkout $tmp_branch; unset $tmp_branch; }; f"ฉันไม่ต้องพิมพ์สาขาที่ฉันเปิดอยู่ดังนั้นถ้าฉันต้องการที่จะรวมdevเข้าด้วยกันmasterและฉันอยู่ในdevตอนนี้ฉันพิมพ์git merge-to master
Steve

2
รุ่นที่ดีกว่ากับ backticks ที่ถูกต้องและไม่มีเสียงสะท้อน:merge-to = "!f() { export tmp_branch=`git branch | grep '* ' | tr -d '* '`; git checkout $1 && git merge $tmp_branch && git checkout $tmp_branch; unset $tmp_branch; }; f"
ไซมอน Epskamp

2
คำสั่ง unset ไม่ถูกต้อง คงที่คือ: merge-to = "! f () {export tmp_branch = git branch | grep '* ' | tr -d '* '; git checkout $ 1 && git merge - no-ff $ tmp_branch && git checkout $ tmp_branch; unset tmp_branch;}; f"
sassman

38

การดัดแปลงเล็กน้อยจากนามแฝง Jefromi ที่ไม่ต้องการให้คุณพิมพ์ในสาขาปัจจุบัน

git merge-to devดังนั้นคุณจะใช้มันที่ชอบ:

สิ่งนี้จะสลับไปที่devสาขารวมกับ CURRENT แล้วจะสลับกลับ

ตัวอย่างเช่นสมมติว่าคุณอยู่ในmasterสาขามันจะรวมต้นแบบเข้ากับ dev และคุณจะยังคงอยู่บนต้นแบบ

มันจะไปที่ dotfiles ของฉันอย่างแน่นอน :)

[alias]
  merge-to = "!gitmergeto() { export tmp_branch=`git branch | grep '* ' | tr -d '* '` && git checkout $1 && git merge $tmp_branch && git checkout $tmp_branch; unset tmp_branch; }; gitmergeto"

6

นี่เก่า แต่ ...

การรวมโซลูชันจาก @ kevin-lyda และ @ dmytrii-nagirniak ด้านบน นามแฝงนี้ผสานสาขาปัจจุบันเป็นสาขาที่ระบุ มันใช้วิธีการรีโมทด้วยและใช้คำสั่ง git เพื่อรับบริบท

[alias]
    merge-to = "!gitmergeto() { git push \"`git rev-parse --show-toplevel`\" `git rev-parse --abbrev-ref HEAD`:$1; } && gitmergeto"

ที่จะใช้เช่น:

git merge-to other-branch-name

4

หากต้องการรวมสาขาปัจจุบันเข้ากับสาขาอื่นโดยไม่ต้องเช็คสาขาอื่น:

ผสานการกรอไปข้างหน้า

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

git branch -f master dev

Caveats:สิ่งนี้จะถือว่าmasterการกระทำที่อยู่ในdevสาขาหรือสาขาอื่น ๆ หากไม่เป็นเช่นนั้นคุณอาจสูญเสียงาน! ซึ่งแตกต่างจากgit mergeที่จะสร้างผสานกระทำ (หรือบ่น) เมื่อไม่สามารถไปข้างหน้าอย่างรวดเร็ววิธีนี้จะบังคับให้ตัวชี้สาขาชี้ไปที่การกระทำอื่นอย่างเงียบ ๆ

สิ่งนี้ยังถือว่าคุณเป็นคนเดียวที่ทำงานกับ repo และ / หรือคุณรู้ว่าคุณกำลังทำอะไรอยู่

เคล็ดลับ:หากคุณทำgit fetchและคุณมีข้อผูกพันใหม่origin/masterคุณสามารถย้ายmasterสาขาได้โดยไม่ต้องใช้:

git branch -f master origin/master

ผสานผ่านการผสานกระทำ

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

หากคุณมีข้อผูกพันในmasterสาขาที่ไม่ได้อยู่ในdevสาขาคุณสามารถ:

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

git checkout -b temp
git merge --no-ff -e master
git branch -f master temp
git checkout dev
git branch -D temp

คำอธิบาย:

  1. ตรวจสอบสาขาชั่วคราวที่ชี้ไปที่การกระทำเดียวกันกับสาขาปัจจุบัน
  2. รวมmasterเข้ากับสาขาชั่วคราวและเปิดใช้ตัวแก้ไขข้อความ หากคุณต้องการให้การผสานดูเหมือนว่าคุณได้รวมdevสาขาเข้าไว้masterให้แก้ไขจากสิ่งนี้:

    Merge branch 'master' into temp
    

    สำหรับสิ่งนี้:

    Merge branch 'dev'
    

    เคล็ดลับ:คุณสามารถใช้-m "Merge branch 'dev'"แทนที่จะ-eเป็นเร็วกว่าได้

  3. อัปเดตmasterตัวชี้สาขาเพื่อชี้ไปที่การผสาน
  4. ตรวจสอบdevสาขา
  5. บังคับลบสาขาชั่วคราว

สิ่งนี้ยังคงสัมผัสแผนผังการทำงานของคุณ มันไม่ได้ย้อนต้นไม้กลับไปสู่สภาพดั้งเดิมmasterเพื่อนำการเปลี่ยนแปลงมาพัฒนาอีกครั้ง บางคนอาจไม่สนใจ แต่สำหรับคนอื่นมันอาจสำคัญ


1

หลายครั้งที่คุณมาจากสาขาคุณต้องการรวมสาขาปัจจุบันเข้าด้วยกัน ในกรณีนั้นคุณสามารถทำได้:

git co - && git merge @{-1}

ตัวอย่างเช่น:

git checkout somebranch      // (while on master)

// add some commits

git co - && git merge @{-1}  // will merge somebranch into master

1

โซลูชันของฉันคล้ายกับคำตอบอื่น ๆ โดยมีข้อแตกต่างดังต่อไปนี้:

  • ฟังก์ชันนี้แบ่งออกเป็นหลายบรรทัดเพื่อให้อ่านง่าย
  • ฟังก์ชั่นการโทรset -exเพื่อให้แต่ละคำสั่งถูกพิมพ์และหากคำสั่งล้มเหลวฟังก์ชั่นออกทันที
  • นามแฝงผ่านการขัดแย้งยกเว้นแรก (สาขาเป้าหมาย) เพื่อ git merge
  • ฟังก์ชั่นนี้มีคำสั่ง null : git mergeซึ่งทำให้การทำงานของแท็บเสร็จสมบูรณ์ด้วยการตั้งค่าเชลล์บางตัว (เช่นgitfastจาก oh-my-zsh)
[alias]
  merge-to = "!f() { : git merge ; \
      set -ex ; \
      local this=$(git rev-parse --abbrev-ref HEAD) ; \
      local target=$1 ; \
      shift ; \
      git checkout $target ; \
      git merge $this \"$@\" ; \
      git checkout $this ; \
    } ; f"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.