Làm thế nào tôi có thể biết nếu một chi nhánh đã được sáp nhập vào chủ?


1140

Tôi có một kho git với nhiều chi nhánh.

Làm thế nào tôi có thể biết những nhánh nào đã được sáp nhập vào nhánh chính?

Câu trả lời:


1793

git branch --merged masterliệt kê các chi nhánh sáp nhập vào chủ

git branch --mergedliệt kê các nhánh được sáp nhập vào HEAD (tức là đỉnh của nhánh hiện tại)

git branch --no-merged liệt kê các chi nhánh chưa được sáp nhập

Theo mặc định, điều này chỉ áp dụng cho các chi nhánh địa phương. Các -alá cờ sẽ hiển thị cả các chi nhánh địa phương và từ xa, và các -rchương trình cờ chỉ các chi nhánh từ xa.


2
Chỉ là một ghi chú bên cạnh, khi tôi cố gắng xem liệu một chi nhánh từ xa đã được hợp nhất, trước tiên tôi thiết lập một nhánh theo dõi cục bộ, xác định trạng thái với git branch --mergedvà sau đó xóa các chi nhánh từ xa và cục bộ.
Kenneth Kalmer

83
Rõ ràng, git branch -a --merged/no-mergedcũng hoạt động, mà không tạo ra một nhánh theo dõi cục bộ trong quá trình.
fresskoma

70
Hoặc chỉ git branch -r --merged/--no-mergedđể tìm chi nhánh từ xa.
Asfand Qazi

5
Có cách nào để xóa các nhánh chưa được hợp nhất thực sự được hợp nhất sau khi nổi loạn không?
Ashfame

9
Lưu ý rằng --merged/--no-mergedcó một đối số cam kết tùy chọn sau nó. Ít nhất là trong phiên bản git của tôi (1.9.1), việc thêm -ahoặc -rcờ sau khi nó gây ra lỗi nghiêm trọng. Thêm -ahoặc -r trước --(no-)merged .
Jonathan Gawrych 10/2/2015

113

Bạn có thể sử dụng git merge-baselệnh để tìm cam kết chung mới nhất giữa hai nhánh. Nếu cam kết đó giống như đầu chi nhánh của bạn, thì chi nhánh đã được hợp nhất hoàn toàn.

Lưu ý rằng git branch -dđiều này đã xảy ra vì nó sẽ từ chối xóa một nhánh chưa được hợp nhất hoàn toàn.


3
Câu trả lời của @ hari đi sâu vào chi tiết hơn về cách sử dụng này.
Muhd

Làm thế nào chúng ta có thể làm điều này tự động / lập trình?
Alexander Mills

1
"chưa được sáp nhập hoàn toàn" ... hoàn toàn sáp nhập vào chi nhánh nào?
Alexander Mills

@AlexanderMills: Vào chi nhánh hiện tại của bạn.
Greg Hewgill

2
@AlexanderMills: git branch -dsẽ từ chối xóa một chi nhánh chưa được sáp nhập vào chi nhánh hiện tại. Không xóa chi nhánh hiện tại .
Greg Hewgill

27

Có một giải pháp giao diện đồ họa là tốt. Chỉ loại

gitk --all

Một cửa sổ ứng dụng mới sẽ nhắc với biểu diễn đồ họa của toàn bộ repo của bạn, nơi rất dễ nhận ra nếu một nhánh đã được hợp nhất hay chưa


17
Để rõ ràng, yêu cầu cài đặt một ứng dụng không phải là một phần của gitmáy khách. Trên Ubuntu , apt-get install gitk.
metame

Trên macOS, nếu bạn đã cài đặt Homebrew, sẽ có brew install git-guiđược gitkdòng lệnh.
chương trình247365

24

Tôi đang sử dụng chức năng bash sau đây như: git-is-merged develop feature/new-feature

git-is-merged () {
  merge_destination_branch=$1
  merge_source_branch=$2

  merge_base=$(git merge-base $merge_destination_branch $merge_source_branch)
  merge_source_current_commit=$(git rev-parse $merge_source_branch)
  if [[ $merge_base = $merge_source_current_commit ]]
  then
    echo $merge_source_branch is merged into $merge_destination_branch
    return 0
  else
    echo $merge_source_branch is not merged into $merge_destination_branch
    return 1
  fi
}

3
Điều này thực sự không hoạt động. Nếu nhánh nguồn đã được sáp nhập vào nhánh đích và sau đó nhánh đích nhận thêm một vài lần xác nhận, nó không hoạt động nữa nhưng tôi không biết tại sao
Alexander Mills


18

Sử dụng git merge-base <commit> <commit> .

Lệnh này tìm (các) tổ tiên chung tốt nhất giữa hai lần xác nhận. Và nếu tổ tiên chung giống hệt với cam kết cuối cùng của một "nhánh", thì chúng ta có thể giả định một cách an toàn rằng một "nhánh" đã được sáp nhập vào chủ.

Dưới đây là các bước

  1. Tìm hàm băm cam kết cuối cùng trên nhánh chính
  2. Tìm hàm băm cam kết cuối cùng trên một "nhánh"
  3. Chạy lệnh git merge-base <commit-hash-step1> <commit-hash-step2>.
  4. Nếu đầu ra của bước 3 giống như đầu ra của bước 2, thì một "nhánh" đã được hợp nhất thành chủ.

Thông tin thêm về git merge-base https://git-scm.com/docs/git-merge-base .


2
Tôi nghĩ rằng điều này sẽ chỉ cho bạn biết nếu các mẹo được hợp nhất. Ví dụ, điều này sẽ không cho bạn biết nếu masterđược sáp nhập vào branch, và sau đó thêm 4 lần xác nhận nữa branch.
mkobit

Tại sao không git log -1 $(git merge-base base-branch feature-branch)và nếu bạn thấy feature-branchtrong đầu ra, sau đó bạn biết chúng được hợp nhất?
Carl G

12

Về chủ đề làm sạch các chi nhánh từ xa

git branch -r | xargs -t -n 1 git branch -r --contains

Điều này liệt kê từng chi nhánh từ xa theo sau là các chi nhánh từ xa mới nhất của họ.

Điều này rất hữu ích để phân biệt các nhánh từ xa đã được hợp nhất nhưng không bị xóa và không được hợp nhất và do đó đang phân rã.

Nếu bạn đang sử dụng 'tig' (giống như gitk nhưng dựa trên thiết bị đầu cuối) thì bạn có thể

tig origin/feature/someones-decaying-feature

để xem lịch sử cam kết của chi nhánh mà không cần phải kiểm tra


3
Làm tốt lắm người đàn ông đó! Rất hữu ích khi bạn hiểu được những gì nó thực sự hiển thị! Ứng dụng GitHub cần kết hợp điều này vào một màn hình trực quan của các chi nhánh của bạn, thay vì một danh sách được sắp xếp theo thứ tự không có thứ bậc!
CMash 3/03/2015

12

Để xác minh các nhánh nào được hợp nhất thành chủ, bạn nên sử dụng các lệnh sau:

  • git branch <flag[-r/-a/none]> --merged master danh sách tất cả các chi nhánh sáp nhập vào chủ.
  • git branch <flag[-r/-a/none]> --merged master | wc -l đếm số lượng của tất cả các chi nhánh sáp nhập vào chủ.

Cờ là:

  • -acờ - (tất cả) hiển thị các chi nhánh từ xa và địa phương
  • -rcờ - (từ xa) chỉ hiển thị các nhánh từ xa
  • <emptyFlag>- chỉ hiển thị các chi nhánh địa phương

ví dụ: git branch -r --merged master sẽ hiển thị cho bạn tất cả các kho lưu trữ từ xa được hợp nhất thành chủ.


5

Dưới đây là các kỹ thuật của tôi khi tôi cần tìm hiểu xem một nhánh đã được hợp nhất hay chưa, ngay cả khi nó có thể bị từ chối để cập nhật với nhánh chính của chúng tôi, đó là một kịch bản phổ biến cho các nhánh tính năng.

Cả hai cách tiếp cận này đều là bằng chứng ngu ngốc, nhưng tôi đã thấy chúng hữu ích nhiều lần.

1 Hiển thị nhật ký cho tất cả các chi nhánh

Sử dụng một công cụ trực quan như gitk hoặc TortoiseGit, hoặc đơn giản là git log với --all, đi qua lịch sử để xem tất cả các sự hợp nhất với nhánh chính. Bạn sẽ có thể phát hiện ra nếu nhánh tính năng cụ thể này đã được hợp nhất hay chưa.

2 Luôn xóa chi nhánh từ xa khi hợp nhất trong một nhánh tính năng

Nếu bạn có thói quen luôn loại bỏ cả nhánh cục bộ và nhánh từ xa khi bạn hợp nhất trong một nhánh tính năng, thì bạn chỉ cần cập nhật và cắt tỉa từ xa trên máy tính khác của mình và các nhánh tính năng sẽ biến mất.

Để giúp ghi nhớ việc này, tôi đã sử dụng tiện ích mở rộng luồng git (phiên bản AVH) để tạo và hợp nhất các nhánh tính năng của mình cục bộ, vì vậy tôi đã thêm móc luồng git sau để hỏi tôi có muốn tự động xóa nhánh từ xa không.

Ví dụ tạo / kết thúc nhánh tính năng

554 Andreas:MyRepo(develop)$ git flow start tmp
Switched to a new branch 'feature/tmp'

Summary of actions:
- A new branch 'feature/tmp' was created, based on 'develop'
- You are now on branch 'feature/tmp'

Now, start committing on your feature. When done, use:

     git flow feature finish tmp

555 Andreas:MyRepo(feature/tmp)$ git flow finish
Switched to branch 'develop'
Your branch is up-to-date with 'if/develop'.
Already up-to-date.

[post-flow-feature-finish] Delete remote branch? (Y/n)
Deleting remote branch: origin/feature/tmp.

Deleted branch feature/tmp (was 02a3356).

Summary of actions:
- The feature branch 'feature/tmp' was merged into 'develop'
- Feature branch 'feature/tmp' has been locally deleted
- You are now on branch 'develop'

556 Andreas:ScDesktop (develop)$

.git / hook / post-Flow-Feature-finish

NAME=$1
ORIGIN=$2
BRANCH=$3

# Delete remote branch
# Allows us to read user input below, assigns stdin to keyboard
exec < /dev/tty

while true; do
  read -p "[post-flow-feature-finish] Delete remote branch? (Y/n) " yn
  if [ "$yn" = "" ]; then
    yn='Y'    
  fi
  case $yn in
      [Yy] ) 
        echo -e "\e[31mDeleting remote branch: $2/$3.\e[0m" || exit "$?"
        git push $2 :$3; 
        break;;
      [Nn] ) 
        echo -e "\e[32mKeeping remote branch.\e[0m" || exit "$?"
        break;;
      * ) echo "Please answer y or n for yes or no.";;
  esac
done

# Stop reading user input (close STDIN)
exec <&-
exit 0

3 Tìm kiếm bằng tin nhắn cam kết

Nếu không phải lúc nào cũng xóa chi nhánh từ xa, bạn vẫn có thể tìm kiếm các cam kết tương tự để xác định xem chi nhánh đã được hợp nhất hay chưa. Cạm bẫy ở đây là nếu chi nhánh từ xa đã bị từ chối đến mức không thể nhận ra, chẳng hạn như xác nhận đè bẹp hoặc thay đổi thông điệp cam kết.

  • Lấy và tỉa tất cả các điều khiển từ xa
  • Tìm tin nhắn của cam kết cuối cùng trên nhánh tính năng
  • Xem nếu một cam kết với cùng một thông điệp có thể được tìm thấy trên nhánh chính

Các lệnh ví dụ trên nhánh chính:

gru                   
gls origin/feature/foo
glf "my message"

Trong cấu hình bash .profile của tôi

alias gru='git remote update -p'
alias glf=findCommitByMessage

findCommitByMessage() {
    git log -i --grep="$1"
}

@anjdeas - bước 1 - làm thế nào để bạn biết những nhánh nào đã được sáp nhập vào chính. Tôi đã xem xét các bản ghi và công cụ gui - và không thể tìm thấy bất cứ nơi nào nó hiển thị rõ ràng điều này ???
Huff

@TheHuff Hãy thử điều này:git log --all --color --graph --decorate --topo-order --date=relative --abbrev-commit --pretty=format:"%C(green)%h %C(red bold)[%<(14)%ad] %Creset%s%Cred%d%C(blue) [%an]"
angensesen

@TheHuff Trong TortoiseGit, nếu bạn ở nhánh chính, nó sẽ hiển thị tất cả các kết hợp thành chính.
angensesen

Cảm ơn - nhưng làm thế nào để tôi biết hợp nhất là gì? Tôi cho rằng tất cả họ đều cam kết - điều này có đúng không?
Huff

@TheHuff: Bạn sẽ thấy trực quan hai luồng / đường dẫn của các cam kết hợp nhất với nhau thành một "hạ lưu" duy nhất (cao hơn trong chế độ xem nhật ký). Cam kết đó là một cam kết hợp nhất. Ngoài ra, trong git logbạn có thể thêm --mergesvào chỉ hiển thị các cam kết hợp nhất. stackoverflow.com/a/25986615/134761
angensesen

4

Dưới đây là một lớp lót nhỏ sẽ cho bạn biết nếu nhánh hiện tại của bạn kết hợp hoặc hết dữ liệu từ một nhánh gốc / nhánh chính từ xa:

$ git fetch && git branch -r --merged | grep -q origin/master && echo Incorporates origin/master || echo Out of date from origin/master

Tôi đã gặp câu hỏi này khi làm việc trên một nhánh tính năng và thường xuyên muốn đảm bảo rằng tôi có công việc gần đây nhất được kết hợp vào nhánh làm việc riêng của mình.

Để khái quát hóa bài kiểm tra này, tôi đã thêm bí danh sau vào ~ / .gitconfig:

[alias]
   current = !git branch -r --merged | grep -q $1 && echo Incorporates $1 || echo Out of date from $1 && :

Sau đó tôi có thể gọi:

$ git current origin/master

để kiểm tra nếu tôi hiện tại.

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.