Hợp nhất chi nhánh phát triển với chủ


764

Tôi có hai chi nhánh là masterdevelopmenttrong Kho lưu trữ GitHub. Tôi đang làm tất cả sự phát triển của tôi trong ngành phát triển như được hiển thị.

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

Bây giờ tôi muốn hợp nhất tất cả các thay đổi trên developmentnhánh vào master. Cách tiếp cận hiện tại của tôi là:

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

Xin vui lòng cho tôi biết nếu thủ tục tôi đang làm là đúng.


7
git pull -uđặt theo dõi ngược dòng cho nhánh (hoặc tất cả các nhánh nếu đẩy nhiều hơn một). Một khi nó được thiết lập theo dõi vẫn tồn tại. Không có lý do để sử dụng nó liên tục.
David Culp

Câu trả lời:


1165

Tôi thường thích hợp nhất mastervào phần developmentđầu tiên để nếu có bất kỳ xung đột nào, tôi có thể giải quyết trong developmentchính chi nhánh và bản thân tôi mastervẫn sạch sẽ.

(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)

Không có nhiều sự khác biệt trong hai cách tiếp cận, nhưng đôi khi tôi nhận thấy rằng tôi không muốn hợp nhất chi nhánh vào masterđó, sau khi hợp nhất chúng, hoặc vẫn còn nhiều việc phải làm trước khi chúng có thể được hợp nhất , vì vậy tôi có xu hướng để lại masterkhông bị ảnh hưởng cho đến khi công cụ cuối cùng.

EDIT: Từ ý kiến

Nếu bạn muốn theo dõi ai đã hợp nhất và khi nào, bạn có thể sử dụng --no-ffcờ trong khi hợp nhất để làm như vậy. Điều này thường chỉ hữu ích khi hợp nhất developmentvào master(bước cuối cùng), bởi vì bạn có thể cần phải hợp nhất mastervào development(bước đầu tiên) nhiều lần trong quy trình làm việc của mình và tạo một nút cam kết cho những điều này có thể không hữu ích lắm.

git merge --no-ff development

71
Có một nhược điểm nhỏ trong cách tiếp cận đó: hợp nhất thực tế để làm chủ rất có thể là hợp nhất chuyển tiếp nhanh và do đó không tạo ra bất kỳ nút cam kết nào. Điều này không có vấn đề gì với mã thực tế trên nhánh, nhưng làm cho nó khó tìm ra sau này, ai đã thực hiện hợp nhất thực tế để làm chủ và tại thời điểm đó. Một sự rõ ràng --no-ffđể hợp nhất thành chủ là cần thiết để khắc phục điều đó.
michas

11
Vâng, chính xác đó là những gì --no-ffdành cho. :)
michas

19
Đó git merge --no-ff developmentchỉ là để sửa lỗi sử dụng @ bầu.
jewbix.cube

2
@sailesh bạn có thể vui lòng cập nhật câu trả lời của bạn để bao gồm cờ git merge, nếu bạn đồng ý với các ý kiến?
Người dùng web

2
@Mars, việc hợp nhất sẽ ghi đè lên một tệp nếu thay đổi cũ là nguồn gốc trực tiếp của cam kết. Ví dụ, hãy A->B->Clàm chủ và A->X->Ylà nhánh dev của bạn. Nếu bạn thay đổi một phần của tệp trong Xđó có thể có xung đột với thay đổi trong Ađó, thì đó sẽ không phải là xung đột, vì Alà tổ tiên của X. Về các thay đổi bị mất, hãy kiểm tra stackoverflow.com/questions/7147680/ trên để phục hồi mọi thay đổi.
Đi thuyền buồm

103

Cá nhân, cách tiếp cận của tôi tương tự như của bạn, với một vài chi nhánh và một số cam kết khi họ trở lại thành thạo.

Một trong những đồng nghiệp của tôi không thích phải chuyển đổi các nhánh quá nhiều và ở lại nhánh phát triển với một cái gì đó tương tự như sau đây được thực hiện từ nhánh phát triển.

git fetch origin master

git merge master

git push origin development:master

Dòng đầu tiên đảm bảo rằng anh ta có bất kỳ cam kết ngược dòng nào đã được thực hiện để làm chủ kể từ lần cuối cùng cập nhật kho lưu trữ cục bộ của mình.

Cái thứ hai kéo những thay đổi đó (nếu có) từ chủ thành phát triển

Cái thứ ba đẩy nhánh phát triển (bây giờ được hợp nhất hoàn toàn với master) lên tới origin / master.

Tôi có thể có quy trình làm việc cơ bản của anh ấy một chút sai, nhưng đó là ý chính của nó.


Cảm ơn! Điều này với tôi làm cho ý nghĩa trực quan hơn.
Jamie Nicholl-Shelley

2
Có - trong hơn 6 năm kể từ khi tôi viết bài này, tôi cũng đã chấp nhận nó - mặc dù với rebaseviệc cập nhật devchi nhánh thay vì merge.
David Culp

32

Giải thích từ dưới lên cho những người đến đây mà không có kiến ​​thức về các chi nhánh.

Logic phát triển nhánh chủ cơ bản là: Bạn chỉ làm việc trên các nhánh khác và chỉ sử dụng chủ để hợp nhất các nhánh khác.

Bạn bắt đầu tạo một nhánh mới theo cách này:

1) Kho lưu trữ bản sao trong thư mục cục bộ của bạn (hoặc tạo một kho lưu trữ mới):

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

2) Tạo một chi nhánh mới. Nó sẽ chứa các tệp mới nhất của kho lưu trữ nhánh chính của bạn

$ git branch new_branch

3) Thay đổi chi nhánh git hiện tại của bạn thành new_branch

$ git checkout new_branch

4) Làm mã hóa, cam kết, như thường lệ

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

5) Khi công việc kết thúc ở nhánh này, hãy hợp nhất với nhánh Master master:

$ 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”)

Cập nhật: Tôi thực sự khuyên bạn nên sử dụng GitKraken cho việc này để xem cây thay đổi trực quan và xem tốt hơn tất cả logic và cam kết.


Tôi thích cách tiếp cận của bạn không làm việc trên chủ. Nhưng hôm nay khi tôi chơi với gitflow, tôi đã tạo ra releasenhánh của chúng tôi develop. Sau đó thêm một tập tin ghi chú phát hành và cam kết. Sau đó kết thúc việc phát hành hợp nhất trở lại cho cả hai master/develop. nhưng chi nhánh chủ của tôi chỉ có ghi chú phát hành mới được thêm vào trong đó. không có tệp nào khác trong các lần phát triển trước đó được cập nhật trong đó.
Amit Shah

nếu bạn làm việc trên một chi nhánh khác ngoài chủ, hãy chắc chắn rằng bạn đã cam kết và đẩy các thay đổi sang chi nhánh đó. Hơn bạn có thể xem các tệp trông như thế nào trên giao diện Đồ họa của github.com hoặc bitbucket.com và thử nhấp vào Hợp nhất ở đó, trên trang web. Nó sẽ cập nhật mọi thứ từ chi nhánh của bạn đến chủ. Nếu chủ có tệp mới hơn, đó sẽ là xung đột và bạn sẽ nhận được thông báo lỗi. Không chắc chắn tôi đã trả lời đủ tốt, xin vui lòng cho tôi nhắn tin nếu không :)
Gediminas

Tôi đang sử dụng sourcetree làm kho lưu trữ GUI và github. Tôi đã thử 2 lần với thử nghiệm phát hành. các bậc thầy không bao giờ cập nhật với các nhánh phát triển mới nhất.
Amit Shah

hãy thử sử dụng trên trang web github.com trực tiếp các tệp của chi nhánh bạn đang làm việc. Họ có bị đẩy không? Nếu có, hãy thử nhấp vào cùng một nhánh - Hợp nhất và bạn sẽ thấy điều gì xảy ra. Theo kinh nghiệm cá nhân của tôi với sourcetree khá tệ - tôi không thể hiểu đầy đủ những gì đang xảy ra trong các chi nhánh của mình
Gediminas

Cảm ơn @Gediminas đã giải thích chi tiết. Tôi đã nhầm lẫn trong các từ khóa git trước khi đọc câu trả lời của bạn .. :)
Dinesh Suthar

21

Sẽ thật tuyệt nếu bạn có thể sử dụng luồng công việc Git Flow . Nó có thể hợp nhất phát triển chi nhánh thành chủ dễ dàng.

Những gì bạn muốn làm chỉ là làm theo hướng dẫn git-Flow được đề cập ở đây:

CÁC BƯỚC:

  • thiết lập dự án git-Flow
  • tạo chi nhánh và hợp nhất mọi thứ để phát triển
  • chạy lệnh git flow release start <version_number>
  • sau đó cung cấp một thông điệp có ý nghĩa cho việc phát hành
  • chạy lệnh git flow release finish <version_number>
  • nó sẽ hợp nhất mọi thứ thành master và thay đổi nhánh thành master .
  • chạy lệnh git pushđể xuất bản các thay đổi cho chủ từ xa .

Để biết thêm thông tin, hãy truy cập trang - http://danielkummer.github.io/git-flow-chcoateet /


1
Giải pháp nếu ai đó sử dụng git Flow!
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

Vâng, điều này là chính xác, nhưng nó trông giống như một quy trình làm việc rất cơ bản, nơi bạn chỉ cần đệm các thay đổi trước khi chúng sẵn sàng để tích hợp. Bạn nên xem xét các quy trình công việc nâng cao hơn mà git hỗ trợ. Bạn có thể thích cách tiếp cận nhánh chủ đề , cho phép bạn làm việc trên nhiều tính năng song song hoặc phương pháp tốt nghiệp giúp mở rộng quy trình công việc hiện tại của bạn một chút.


6

Nếu bạn đang dùng Mac hoặc Ubuntu, hãy chuyển đến thư mục làm việc của chi nhánh. Trong nhà ga

giả sử haritorev là tên chi nhánh.

git checkout master

nếu có các tệp không được theo dõi hoặc không được cam kết, bạn sẽ gặp lỗi và bạn phải cam kết hoặc xóa tất cả các tệp không bị theo dõi hoặc không được cam kết.

git merge harisdev 

git push origin master

Một lệnh cuối cùng để xóa chi nhánh.

$ git branch -d harisdev

Điều gì ở đây là cụ thể cho Mac hoặc Ubuntu?
Talonx

Lấy làm tiếc. Không có câu trả lời nào khác đề cập rằng các lệnh nên được đưa ra trong Terminal và lệnh xóa chi nhánh. Thật ra tôi chỉ muốn thêm lệnh xóa chi nhánh để nhà phát triển không gây rối với cùng chi nhánh trong tương lai. Tôi đang sử dụng Mac, vì vậy tôi đã đề cập đến nó. Câu hỏi của bạn là hợp lệ và không có lệnh nào trong số này là dành riêng cho Mac hoặc Ubuntu.
Haris Np

Cảm ơn đã làm rõ.
Talonx

5

Bước 1

Tạo và chuyển sang một nhánh "dev" mới, trong đó các tệp git cục bộ của bạn được đồng bộ hóa với nhánh từ xa nhưng nhánh "dev" chưa tồn tại.

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.

Bước 2

Thực hiện các thay đổi của bạn cho nhánh "dev" (hiện tại của bạn nếu bạn làm theo bước 1), cam kết và đẩy chúng đến nhánh "dev" từ xa.

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.

Bước 3

Hợp nhất nhánh "dev" của bạn vào "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

Đây là cách tôi thường làm nó. Đầu tiên, chắc chắn rằng bạn đã sẵn sàng để hợp nhất các thay đổi của bạn thành chủ.

  1. Kiểm tra xem sự phát triển có được cập nhật với những thay đổi mới nhất từ ​​máy chủ từ xa của bạn với git fetch
  2. Khi quá trình tìm nạp được hoàn thành git checkout master.
  3. Đảm bảo nhánh chính có các bản cập nhật mới nhất bằng cách thực thi git pull
  4. Khi các chế phẩm đã được hoàn thành, bạn có thể bắt đầu hợp nhất với git merge development
  5. Đẩy các thay đổi với git push -u origin mastervà bạn đã hoàn tất.

Bạn có thể tìm hiểu thêm về việc hợp nhất git trong bài viết.


3

1) Về phát triển chi nhánh, kiểm tra trạng thái git bằng lệnh sau:

git status

Không nên có mã không được cam kết. Nếu có, hãy đẩy mã của bạn lên nhánh Phát triển:

git add *

git commit -m "My initial commit message"

git push origin Development

2) Trên nhánh Phát triển, chạy theo hai lệnh:

git branch -f master HEAD

git push -f origin master

Nó sẽ đẩy mã chi nhánh phát triển của bạn lên nhánh chính.


Điều này có thúc đẩy tất cả các cam kết phát triển thành chủ hay chỉ đơn giản là thêm một cam kết mới vào chủ?
cuộn

1
Làm thế nào điều này thực sự hoạt động? cụ thể là "git chi nhánh" khi bạn đang phát triển trông như điên. Làm thế nào bạn có thể tạo một nhánh mới gọi là master, nếu đã có một nhánh gọi là master? tài liệu nói rằng -f thực hiện điều này: Đặt lại <tên nhánh> thành <điểm bắt đầu>. Điều đó có nghĩa là gì?
John Little

Không phải lực lượng này đẩy chủ địa phương lên chủ từ xa sao? Đây có vẻ là một ý tưởng tồi nếu bạn đang làm việc trong một nhóm.
Nick

-fkhông được khuyến khích.
DawnSong

2

Dựa trên @Sailesh và @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)

Lệnh đầu tiên sẽ đảm bảo bạn có tất cả các cam kết ngược dòng được thực hiện cho chủ từ xa, với phản hồi của sailesh sẽ không xảy ra.

Thứ hai sẽ thực hiện hợp nhất và tạo xung đột mà sau đó bạn có thể giải quyết.

Sau khi làm như vậy, cuối cùng bạn có thể kiểm tra master để chuyển sang master.

Sau đó, bạn hợp nhất nhánh phát triển lên chủ địa phương. Cờ no-ff sẽ tạo một nút cam kết trong tổng thể để toàn bộ hợp nhất có thể theo dõi được.

Sau đó, bạn có thể cam kết và đẩy hợp nhất của bạn.

Quy trình này sẽ đảm bảo có một cam kết hợp nhất từ ​​phát triển đến thành thạo mà mọi người có thể nhìn thấy, sau đó nếu họ nhìn vào nhánh phát triển, họ có thể thấy các cam kết riêng lẻ mà bạn đã thực hiện cho nhánh đó trong quá trình phát triển.

Tùy chọn, bạn có thể sửa đổi cam kết hợp nhất của mình trước khi bạn đẩy nó, nếu bạn muốn thêm một bản tóm tắt về những gì đã được thực hiện trong nhánh phát triển.

EDIT: câu trả lời ban đầu của tôi đã gợi ý rằng git merge masterkhông làm gì cả, tốt hơn là nên làm git merge FETCH_HEADsau khi lấy nguồn gốc / chủ


2

Khi bạn 'thanh toán' chi nhánh phát triển, bạn ...

 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

Nếu bạn đang sử dụng gerrit, các lệnh sau hoạt động hoàn hảo.

git checkout master
git merge --no-ff development

Bạn có thể lưu với thông điệp cam kết mặc định. Hãy chắc chắn, id thay đổi đã được tạo. Bạn có thể sử dụng lệnh sau để đảm bảo.

git commit --amend

Sau đó đẩy bằng lệnh sau.

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

Bạn có thể gặp một thông báo lỗi như dưới đây.

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

Để giải quyết vấn đề này, quản trị viên dự án gerrit phải tạo một tham chiếu khác trong gerrit có tên 'refs / for / refs / Heads / master' hoặc 'refs / for / refs / Heads / *' (sẽ bao gồm tất cả các chi nhánh trong tương lai). Sau đó, cấp quyền 'Đẩy hợp nhất' cho tham chiếu này và quyền 'Gửi' nếu được yêu cầu để gửi GCR.

Bây giờ, hãy thử lại lệnh đẩy ở trên và nó sẽ hoạt động.

Tín dụng:

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

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


1

Tôi nghĩ giải pháp đơn giản nhất sẽ là

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

Điều này cũng bảo tồn lịch sử của tất cả các chi nhánh đang sử dụng


-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
Đẩy mạnh khi bạn thấy lỗi đó gần như không bao giờ là điều chính xác phải làm, trừ khi bạn rất chắc chắn rằng bạn biết tại sao chi nhánh địa phương của bạn bị thiếu các cam kết từ chi nhánh từ xa. Nói chung, tốt hơn là quay lại bước 3 và pullmột lần nữa. Ngoài ra, không rõ giá trị của câu trả lời này so với câu trả lời hiện có.
Kyle Strand
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.