ผสานสาขาพัฒนากับเจ้านาย


763

ฉันมีสองสาขาคือmasterและdevelopmentในที่เก็บ GitHub ฉันทำทุกอย่างเพื่อการพัฒนาในสาขาการพัฒนาตามที่แสดง

git branch development
git add *
git commit -m "My initial commit message"
git push -u origin development

ตอนนี้ผมต้องการที่จะผสานการเปลี่ยนแปลงทั้งหมดในสาขาเข้าไปในdevelopment masterแนวทางปัจจุบันของฉันคือ:

git checkout master 
git merge development
git push -u origin master 

โปรดแจ้งให้เราทราบหากขั้นตอนที่ฉันกำลังติดตามนั้นถูกต้อง


7
git pull -uตั้งค่าการติดตามอัปสตรีมสำหรับสาขา (หรือทุกสาขาหากกดมากกว่าหนึ่ง) เมื่อมีการตั้งค่าการติดตามยังคงมีอยู่ ไม่มีเหตุผลที่จะใช้อย่างต่อเนื่อง
David Culp

คำตอบ:


1164

โดยทั่วไปฉันชอบที่จะรวมmasterเป็นdevelopmentคนแรกเพื่อที่ว่าหากมีข้อขัดแย้งใด ๆ ฉันสามารถแก้ไขในdevelopmentสาขาของตัวเองและฉันmasterยังคงสะอาด

(on branch development)$ git merge master
(resolve any merge conflicts if there are any)
git checkout master
git merge development (there won't be any conflicts now)

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

แก้ไข: จากความคิดเห็น

หากคุณต้องการติดตามว่าใครทำผสานและเวลาคุณสามารถใช้การ--no-ffตั้งค่าสถานะในขณะที่ผสานเพื่อทำเช่นนั้น นี้จะเป็นประโยชน์โดยทั่วไปเท่านั้นเมื่อผสานdevelopmentลงในmaster(ขั้นตอนสุดท้าย) เพราะคุณอาจต้องผสานmasterเข้าdevelopment(ขั้นตอนแรก) หลายครั้งในขั้นตอนการทำงานของคุณและสร้างโหนดกระทำเหล่านี้อาจจะไม่ได้มีประโยชน์มาก

git merge --no-ff development

71
มีข้อเสียเปรียบเล็กน้อยในวิธีการดังกล่าว: การผสานที่เกิดขึ้นจริงกับต้นแบบเป็นไปได้มากที่สุดว่าเป็นการผสานที่รวดเร็วไปข้างหน้าดังนั้นจึงไม่สร้างโหนดการส่งข้อมูลใด ๆ ไม่มีปัญหากับรหัสจริงในสาขา แต่ทำให้ยากต่อการค้นหาในภายหลังผู้ที่ทำการผสานจริงกับต้นแบบและเวลาใด --no-ffจำเป็นต้องมีการผสานกับหลักอย่างชัดเจนเพื่อแก้ไข
มิชา

11
ใช่ว่าเป็นสิ่งที่--no-ffมีไว้สำหรับ :)
michas

19
นั่นเป็นgit merge --no-ff developmentเพียงการแก้ไขการใช้งานของ @ elect
jewbix.cube

2
@sailesh คุณสามารถโปรดอัปเดตคำตอบของคุณเพื่อรวมธง git merge ถ้าคุณเห็นด้วยกับความคิดเห็น?
ผู้ใช้เว็บ

2
@Mars การรวมจะแทนที่ไฟล์ถ้าการเปลี่ยนแปลงเก่าเป็นบรรพบุรุษโดยตรงของการกระทำ ตัวอย่างเช่นให้A->B->Cเป็นหลักและA->X->Yเป็นสาขา dev ของคุณ ถ้าคุณเปลี่ยนส่วนหนึ่งของไฟล์ในXซึ่งอาจจะมีความขัดแย้งกับการเปลี่ยนแปลงในA, มันจะไม่เป็นความขัดแย้งเพราะเป็นบรรพบุรุษของA Xเกี่ยวกับการเปลี่ยนแปลงที่สูญหายลองดูstackoverflow.com/questions/7147680/…เพื่อกู้คืนการเปลี่ยนแปลงใด ๆ
Sailesh

103

โดยส่วนตัวแล้ววิธีการของฉันก็คล้ายกับของคุณด้วยกิ่งอีกสองสามและบางส่วนของการกระทำเมื่อพวกเขากลับไปที่หลัก

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

git fetch origin master

git merge master

git push origin development:master

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

ที่สองดึงการเปลี่ยนแปลงเหล่านั้น (ถ้ามี) จากต้นแบบไปสู่การพัฒนา

ที่สามผลักสาขาการพัฒนา (ตอนนี้ผสานอย่างเต็มที่กับต้นแบบ) ถึงต้นกำเนิด / ต้นแบบ

ฉันอาจมีขั้นตอนการทำงานขั้นพื้นฐานของเขาผิดเล็กน้อย แต่นั่นเป็นส่วนสำคัญของมัน


ขอบคุณ! สำหรับฉันนี้ทำให้เข้าใจได้ง่ายขึ้น
Jamie Nicholl-Shelley

2
ใช่ - ใน 6 ปีนับตั้งแต่ที่ผมเขียนนี้ผมเกินไปได้นำมัน - แม้จะมีrebaseการปรับปรุงสาขาแทนdev merge
David Culp

32

คำอธิบายจากด้านล่างสำหรับผู้ที่มาที่นี่โดยไม่มีความรู้สาขาใด ๆ

ตรรกะการพัฒนาสาขาหลักพื้นฐานคือ: คุณทำงานกับสาขาอื่นและใช้หลักเท่านั้นเพื่อรวมสาขาอื่น

คุณเริ่มสร้างสาขาใหม่ด้วยวิธีนี้:

1) โคลนที่เก็บใน dir ท้องถิ่นของคุณ (หรือสร้างที่เก็บใหม่):

$ cd /var/www
$ git clone git@bitbucket.org:user_name/repository_name.git

2) สร้างสาขาใหม่ มันจะมีไฟล์ล่าสุดของที่เก็บสาขาหลักของคุณ

$ git branch new_branch

3) เปลี่ยนสาขา git ปัจจุบันของคุณเป็น new_branch

$ git checkout new_branch

4) ทำการเข้ารหัส, กระทำ, ตามปกติ ...

$ git add .
$ git commit -m “Initial commit”
$ git push (pushes commits only to “new_branch”)

5) เมื่องานในสาขานี้เสร็จสิ้นให้รวมกับสาขา“ มาสเตอร์”:

$ git merge master
$ git checkout master (goes to master branch)
$ git merge development (merges files in localhost. Master shouldn’t have any  commits ahead, otherwise there will be a need for pull and merging code by hands!)
$ git push (pushes all “new_branch” commits to both branches - “master” and “new_branch”)

อัปเดต: ฉันขอแนะนำให้ใช้ GitKraken สำหรับสิ่งนี้เพื่อดูแผนผังการเปลี่ยนแปลงและเห็นตรรกะและข้อผูกพันที่ดีกว่าทั้งหมด


ฉันชอบวิธีการของคุณที่ไม่ได้ทำงานกับอาจารย์ แต่วันนี้เมื่อฉันกำลังเล่นกับ gitflow ฉันสร้างสาขาของเราrelease developจากนั้นเพิ่มไฟล์บันทึกย่อประจำรุ่นและยืนยัน master/developเสร็จแล้วปล่อยที่ผสานกลับไปทั้งสอง แต่สาขาหลักของฉันมีบันทึกย่อประจำรุ่นที่เพิ่งเพิ่มเข้าไปใหม่ ไม่มีไฟล์อื่น ๆ ระหว่างการคอมมิชชันการพัฒนาก่อนหน้านี้ที่ถูกอัพเดต
Amit Shah

หากคุณทำงานในสาขาอื่นที่ไม่ใช่สาขาให้แน่ใจว่าคุณได้ยอมรับและผลักดันการเปลี่ยนแปลงไปยังสาขานั้น กว่าที่คุณจะสามารถดูได้ว่าไฟล์มีลักษณะอย่างไรบนอินเทอร์เฟซกราฟิกของ github.com หรือ bitbucket.com แล้วลองคลิกรวมที่นั่นบนเว็บไซต์ ควรอัปเดตทุกอย่างจาก branche ของคุณเป็นหลัก หากต้นแบบมีไฟล์ที่ใหม่กว่ามันควรเป็นข้อขัดแย้งและคุณจะได้รับข้อความแสดงข้อผิดพลาด ไม่แน่ใจว่าผมมีคำตอบที่ดีพอโปรดให้ฉันข้อความหากไม่ได้ :)
Gediminas

ฉันใช้ sourcetree เป็นที่เก็บ GUI และ github ฉันพยายาม 2 ครั้งด้วยการทดสอบการเปิดตัว อาจารย์ไม่เคยปรับปรุงด้วยสาขาพัฒนาล่าสุด
Amit Shah

พยายามที่จะใช้ไฟล์สดบนเว็บไซต์ github.com ของสาขาที่คุณกำลังทำงานอยู่ พวกเขาผลักหรือไม่ ถ้าใช่ลองคลิกที่สาขาเดียวกัน - รวมแล้วคุณจะเห็นสิ่งที่เกิดขึ้น จากประสบการณ์ส่วนตัวของฉันกับ sourcetree นั้นค่อนข้างแย่ - ฉันไม่สามารถเข้าใจได้อย่างเต็มที่ว่าเกิดอะไรขึ้นในสาขาของฉัน
Gediminas

ขอบคุณ @Gediminas สำหรับคำอธิบายโดยละเอียด ฉันสับสนในคำหลักที่คอมไพล์ก่อนที่จะอ่านคำตอบของคุณ .. :)
Dinesh Suthar

21

มันจะดีมากถ้าคุณสามารถใช้เวิร์กโฟลว์ Git ไหล มันสามารถรวมการพัฒนาสาขาเป็นหลักได้อย่างง่ายดาย

สิ่งที่คุณต้องการทำเพียงทำตามคำสั่ง git-flow ที่กล่าวถึงที่นี่:

ขั้นตอน:

  • ติดตั้งโครงการ git-flow
  • สร้างสาขาและผสานทุกอย่างเพื่อพัฒนา
  • เรียกใช้คำสั่ง git flow release start <version_number>
  • จากนั้นให้ข้อความที่มีความหมายสำหรับการเปิดตัว
  • เรียกใช้คำสั่ง git flow release finish <version_number>
  • มันจะรวมทุกอย่างลงในต้นแบบและเปลี่ยนสาขาต้นแบบ
  • เรียกใช้คำสั่งgit pushในการเผยแพร่การเปลี่ยนแปลงไปยังที่ห่างไกลต้นแบบ

สำหรับข้อมูลเพิ่มเติมโปรดเยี่ยมชมหน้า - http://danielkummer.github.io/git-flow-cheatsheet/


1
วิธีแก้ปัญหาถ้ามีคนใช้กระแส git!
Csaba Toth

21
1. //pull the latest changes of current development branch if any        
git pull (current development branch)

2. //switch to master branch
git checkout master 

3. //pull all the changes if any
git pull

4. //Now merge development into master    
git merge development

5. //push the master branch
git push origin master

9

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


6

หากคุณใช้ Mac หรือ Ubuntu ให้ไปที่โฟลเดอร์ทำงานของสาขา ในอาคารผู้โดยสาร

สมมติว่า harisdev คือ branchname

git checkout master

หากมีไฟล์ที่ไม่ได้ติดตามหรือไม่มีข้อผูกมัดคุณจะได้รับข้อผิดพลาดและคุณต้องยอมรับหรือลบไฟล์ที่ไม่ได้ติดตามหรือไม่ได้รับการผูกมัดทั้งหมด

git merge harisdev 

git push origin master

หนึ่งคำสั่งสุดท้ายเพื่อลบสาขา

$ git branch -d harisdev

นี่คืออะไรที่เฉพาะเจาะจงสำหรับ Mac หรือ Ubuntu?
talonx

ขอโทษ ไม่มีคำตอบอื่นใดที่กล่าวถึงว่าควรให้คำสั่งในเทอร์มินัลและคำสั่งสำหรับการลบสาขา อันที่จริงฉันแค่อยากจะเพิ่มคำสั่งสำหรับการลบสาขาเพื่อที่นักพัฒนาจะไม่ยุ่งกับสาขาเดียวกันในอนาคต ฉันใช้ Mac ดังนั้นฉันจึงพูดถึงมัน คำถามของคุณถูกต้องและไม่มีคำสั่งเหล่านี้เฉพาะสำหรับ Mac หรือ Ubuntu
Haris Np

ขอบคุณสำหรับการชี้แจง
talonx

5

ขั้นตอนที่ 1

สร้างและเปลี่ยนเป็นสาขา "dev" ใหม่ซึ่งไฟล์ git ในเครื่องของคุณซิงค์กับรีโมตแล้ว แต่ยังไม่มีสาขา "dev"

git branch dev # create
git checkout dev # switch
# No need to git add or git commit, the current
# branch's files will be cloned to the new branch by-default.
git push --set-upstream origin dev # push the "dev" branch to the remote.

ขั้นตอนที่ 2

ทำการเปลี่ยนแปลงสาขา "dev" (ปัจจุบันของคุณหากคุณทำตามขั้นตอนที่ 1) กระทำและผลักดันพวกเขาไปยังสาขา "dev" ระยะไกล

git add .
git commit -S -m "my first commit to the dev branch" # remove the -S if you're not "secure", secure = when you already setup crypto private and public keys (i.e "verified" green sign in github)
git push -u origin dev # push the changes to the remote, -u origin dev is optional but good to use.

ขั้นตอนที่ 3

รวมสาขา "dev" ของคุณเข้ากับ "master"

git checkout dev # switch to "dev" branch if you're not already.
git merge master # optionally, this command is being used to resolve any conflicts if you pushed any changes to your "master" but "dev" doesn't have that commit.
git checkout master # switch to "master", which is the branch you want to be merged.
git merge --no-ff dev # merge the "dev" branch into the "master" one.

4

นี่คือวิธีที่ฉันมักจะทำ ก่อนอื่นให้แน่ใจว่าคุณพร้อมที่จะรวมการเปลี่ยนแปลงของคุณเข้ากับต้นแบบ

  1. ตรวจสอบว่าการพัฒนาเป็นปัจจุบันด้วยการเปลี่ยนแปลงล่าสุดจากเซิร์ฟเวอร์ระยะไกลของคุณด้วย git fetch
  2. git checkout masterเมื่อดึงข้อมูลเป็นที่เรียบร้อยแล้ว
  3. ตรวจสอบให้แน่ใจว่าสาขาหลักมีการอัพเดทล่าสุดโดยการดำเนินการ git pull
  4. เมื่อการเตรียมการเสร็จสมบูรณ์คุณสามารถเริ่มผสานกับ git merge development
  5. ผลักดันการเปลี่ยนแปลงด้วยgit push -u origin masterและคุณเสร็จแล้ว

คุณสามารถหาข้อมูลเพิ่มเติมเกี่ยวกับการรวมคอมไพล์ในบทความ


3

1) ในการพัฒนาสาขาตรวจสอบสถานะ git โดยใช้คำสั่งต่อไปนี้:

git status

ไม่ควรมีรหัสที่ไม่มีข้อผูกมัด หากเป็นเช่นนั้นให้กดรหัสของคุณบนสาขาการพัฒนา:

git add *

git commit -m "My initial commit message"

git push origin Development

2) บนสาขาการพัฒนารันสองคำสั่งต่อไปนี้:

git branch -f master HEAD

git push -f origin master

มันจะผลักดันรหัสสาขาการพัฒนาของคุณไปยังสาขาหลัก


สิ่งนี้จะผลักดันให้การพัฒนาทั้งหมดมุ่งมั่นที่จะเป็นหลักเช่นกันหรือเพียงแค่เพิ่มความมุ่งมั่นใหม่เป็นหลัก?
ม้วน

1
มันใช้งานได้จริงอย่างไร โดยเฉพาะ "นายสาขา git" เมื่อคุณอยู่ในการพัฒนาดูเหมือนบ้า คุณจะสร้างสาขาใหม่ที่ชื่อว่า master ได้อย่างไรถ้ามีสาขาที่เรียกว่า master อยู่แล้ว เอกสารบอกว่า -f ทำสิ่งนี้: รีเซ็ต <branchname> เป็น <startpoint> สิ่งนี้หมายความว่า?
John Little

กำลังนี้ผลักเจ้านายท้องถิ่นไปยังนายรีโมทหรือไม่? ดูเหมือนว่าเป็นความคิดที่ไม่ดีถ้าคุณทำงานเป็นทีม
Nick

-fไม่แนะนำ
DawnSong

2

อิงจาก @Sailesh และ @DavidCulp:

(on branch development)
$ git fetch origin master
$ git merge FETCH_HEAD
(resolve any merge conflicts if there are any)
$ git checkout master
$ git merge --no-ff development (there won't be any conflicts now)

คำสั่งแรกจะทำให้แน่ใจว่าคุณได้ทำข้อตกลงต้นน้ำทั้งหมดกับต้นแบบระยะไกลด้วยการตอบกลับของ Sailesh ที่จะไม่เกิดขึ้น

ที่สองจะทำการผสานและสร้างความขัดแย้งที่คุณสามารถแก้ไขได้

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

จากนั้นคุณรวมสาขาการพัฒนาเข้ากับเจ้านายท้องถิ่น แฟล็ก no-ff จะสร้างโหนดการยอมรับในต้นแบบเพื่อให้การผสานทั้งหมดสามารถติดตามได้

หลังจากนั้นคุณสามารถคอมมิชชันและผลักดันการผสานของคุณ

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

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

แก้ไข: คำตอบเดิมของฉันแนะนำสิ่งgit merge masterที่ไม่ได้ทำอะไรเลยดีกว่าที่จะทำgit merge FETCH_HEADหลังจากดึงต้นกำเนิด / ต้นแบบ


2

เมื่อคุณ 'ชำระเงิน' สาขาการพัฒนาของคุณ ...

 git add .
 git commit -m "first commit"
 git push origin dev
 git merge master

 git checkout master 
 git merge dev
 git push origin master 

1

หากคุณใช้ gerrit คำสั่งต่อไปนี้จะทำงานได้อย่างสมบูรณ์

git checkout master
git merge --no-ff development

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

git commit --amend

จากนั้นกดคำสั่งต่อไปนี้

git push origin HEAD:refs/for/refs/heads/master

คุณอาจพบข้อความแสดงข้อผิดพลาดเช่นด้านล่าง

! [remote rejected] HEAD -> refs/for/refs/heads/master (you are not allowed to upload merges)

ในการแก้ไขปัญหานี้ผู้ดูแลโครงการ gerrit ต้องสร้างการอ้างอิงอื่นใน gerrit ชื่อ 'refs / for / refs / heads / master' หรือ 'refs / for / refs / heads / *' (ซึ่งจะครอบคลุมสาขาทั้งหมดในอนาคต) จากนั้นให้สิทธิ์ 'Push Merge Commit' เพื่อการอ้างอิงนี้และการอนุญาต 'ส่ง' หากจำเป็นต้องส่ง GCR

ทีนี้ลองคำสั่ง push ด้านบนอีกครั้งและมันก็ใช้ได้ดี

เครดิต:

https://github.com/ReviewAssistant/reviewassistant/wiki/Merging-branches-in-Gerrit

https://stackoverflow.com/a/21199818/3877642


1

ฉันคิดว่าทางออกที่ง่ายที่สุดจะเป็น

git checkout master
git remote update
git merge origin/Develop -X theirs
git commit -m commit -m "New release"
git push --recurse-submodules=check --progress "origin" refs/heads/Master

สิ่งนี้ยังเก็บรักษาประวัติของสาขาทั้งหมดที่ใช้งานอยู่


-4
1. //push the latest changes of current development branch if any        
git push (current development branch)

2. //switch to master branch
git checkout master 

3. //pull all the changes if any from (current development branch)
git pull origin (current development branch)

4. //Now merge development into master    
git merge development

5. //push the master branch
git push origin master

Error
To https://github.com/rajputankit22/todos-posts.git
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'https://github.com/rajputankit22/todos-posts.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

Then Use 
5. //push the master branch forcefully
git push -f origin master

1
การกดปุ่มบังคับเมื่อคุณเห็นข้อผิดพลาดนั้นแทบจะไม่ถูกต้องนักเว้นแต่คุณจะมั่นใจมากว่าคุณรู้ว่าเหตุใดสาขาในพื้นที่ของคุณจึงขาดหายไปจากสาขาระยะไกล โดยทั่วไปจะดีกว่ามากหากย้อนกลับไปยังขั้นตอนที่ 3 และpullอีกครั้ง นอกจากนี้ยังไม่ชัดเจนว่าคำตอบนี้เพิ่มมูลค่าเมื่อเปรียบเทียบกับคำตอบที่มีอยู่
Kyle Strand
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.