Làm cách nào tôi có thể nhận được danh sách các chi nhánh Git, được sắp xếp theo cam kết gần đây nhất?


1324

Tôi muốn có một danh sách tất cả các nhánh trong kho Git với các nhánh "tươi nhất" ở trên cùng, trong đó nhánh "tươi nhất" là nhánh được cam kết gần đây nhất (và do đó, nhiều khả năng là một nhánh Tôi muốn chú ý đến).

Có cách nào để tôi có thể sử dụng Git để (a) sắp xếp danh sách các chi nhánh theo cam kết mới nhất hoặc (b) lấy danh sách các chi nhánh cùng với ngày cam kết cuối cùng của mỗi người, theo một dạng định dạng nào đó có thể đọc được bằng máy không?

Trường hợp xấu nhất, tôi luôn có thể chạy git branchđể lấy danh sách tất cả các chi nhánh, phân tích đầu ra của nó và sau đó git log -n 1 branchname --format=format:%cicho từng chi nhánh, để có được ngày cam kết của mỗi chi nhánh. Nhưng điều này sẽ chạy trên một hộp Windows, trong đó việc tạo ra một quy trình mới tương đối tốn kém, do đó, việc khởi chạy Git thực thi một lần trên mỗi nhánh có thể bị chậm nếu có nhiều nhánh. Có cách nào để làm tất cả điều này với một lệnh không?


2
stackoverflow.com/a/2514279/1804124 Có câu trả lời tốt hơn.
Spundun

12
@Spundun, bạn mất tôi ở đó. Làm thế nào là sự kết hợp của nhiều lệnh, bao gồm các công cụ được truyền qua perl và sed, "tốt hơn" so với sử dụng một lệnh mà Git đã có?
Joe White

37
@Spundun liên quan đến câu trả lời git for-each-reftừ Jakub Narębski: bạn có thể nhận các nhánh từ xa đi qua refs/remotes/thay vì refs/heads/(hoặc bạn có thể vượt qua cả hai, được phân tách bằng khoảng trắng); refs/tags/cho các thẻ, hoặc chỉ refs/cho cả ba loại.
jakub.g

4
Bắt đầu git 2.7 (Q4 2015), không còn nữa for-each-ref! Bạn sẽ sử dụng trực tiếp git branch --sort=-committerdate: xem câu trả lời của tôi dưới đây
VonC

1
Có thể là bản sao của stackoverflow.com/questions/9236219/
Kẻ

Câu trả lời:


1874

Sử dụng --sort=-committerdatetùy chọn của git for-each-ref;

Cũng có sẵn kể từ Git 2.7.0 cho git branch:

Cách sử dụng cơ bản:

git for-each-ref --sort=-committerdate refs/heads/

# Or using git branch (since version 2.7.0)
git branch --sort=-committerdate  # DESC
git branch --sort=committerdate  # ASC

Kết quả:

Kết quả

Sử dụng nâng cao:

git for-each-ref --sort=committerdate refs/heads/ --format='%(HEAD) %(color:yellow)%(refname:short)%(color:reset) - %(color:red)%(objectname:short)%(color:reset) - %(contents:subject) - %(authorname) (%(color:green)%(committerdate:relative)%(color:reset))'

Kết quả:

Kết quả


15
Hoàn hảo! Tôi thậm chí có thể giới hạn đầu ra chỉ là tên ref bằng cách nối thêm --format=%(refname).
Joe White

35
Điều này tốt hơn cho tôi:git for-each-ref --sort=-committerdate refs/heads/ --format='%(refname) %(committerdate) %(authorname)' | sed 's/refs\/heads\///g'
saeedgnu

2
@ilius: tại sao không dùng :shortname?
Jakub Narębski

37
@ilius: Như @BeauSmith đã viết : git for-each-ref --sort=-committerdate --format='%(refname:short)' refs/heads/. manit git-for-Each-ref (1) cho biết: Đối với một tên viết tắt không mơ hồ của phần bổ sung ref :short.
Jakub Narębski

76
Đây là phiên bản được tô màu bao gồm băm, tin nhắn, được sắp xếp tăng dần dựa trên ngày cam kết, với tuổi tương đối của lần xác nhận cuối cùng trên mỗi chi nhánh. Tôi đã đánh cắp tất cả các ý tưởng từ các bạn ở trên. Nó nằm trong .gitconfig của tôi trong [alias]phần này và tôi thích nó. br = for-each-ref --sort=committerdate refs/heads/ --format='%(HEAD) %(color:yellow)%(refname:short)%(color:reset) - %(color:red)%(objectname:short)%(color:reset) - %(contents:subject) - %(authorname) (%(color:green)%(committerdate:relative)%(color:reset))'
Michael Percy

124

Danh sách tên chi nhánh Git, được sắp xếp theo cam kết gần đây nhất

Mở rộng câu trả lời của Jakubmẹo của Joe , phần sau đây sẽ loại bỏ "refs / Heads /" để đầu ra chỉ hiển thị tên chi nhánh:


Chỉ huy:

git for-each-ref --count=30 --sort=-committerdate refs/heads/ --format='%(refname:short)'

Kết quả:

Chi nhánh Git gần đây


4
Bạn cũng có thể sử dụng --format=%(refname:short)thay vì dựa vào cut.
Chaitanya Gupta

3
Có cách nào để làm điều này cho kho lưu trữ REMote không?
Allan Bowe

10
aah - @ jakub.g đã giải thích: bạn có thể nhận các nhánh từ xa chuyển refs / điều khiển từ xa / thay vì refs / Heads /. Hoàn hảo!!
Allan Bowe

Tôi thích cái này, nếu bạn đang cố gắng đặt bí danh cho nó, điều mà tôi đã làm, để git rbnhớ bao quanh lệnh trong ngoặc kép:git config --global alias.rb "for-each-ref --count=20 --sort=-committerdate refs/heads/ --format=\'%(refname:short)\'"
Michael Discenza

2
Và bây giờ bạn có thể làm điều này với git branch, do đó, việc nhận cục bộ, từ xa hoặc tất cả các nhánh hoạt động như trên git-Branch (tức là -r, -a). git branch -r --sort=committerdate --format='%(HEAD) %(color:yellow)%(refname:short)%(color:reset) - %(color:red)%(objectname:short)%(color:reset) - %(contents:subject) - %(authorname) (%(color:green)%(committerdate:relative)%(color:reset))'
phord

89

Đây là mã tối ưu, kết hợp hai câu trả lời khác:

git for-each-ref --sort=-committerdate refs/heads/ --format='%(committerdate:short) %(authorname) %(refname:short)'

10
Ngay cả một chút mor được tối ưu hóa để có được đầu ra dạng bảng:git for-each-ref --sort=-committerdate refs/heads/ --format='%(committerdate:short) %(authorname) %(refname:short)'
schoetbi

2
vì một số lý do, tôi đã phải sử dụng dấu ngoặc kép trên các cửa sổ, nhưng nếu không thì chúng chỉ hoạt động tốt :)
amenthes

1
@schoetbi Mã đó trông giống hệt mã từ nikolay, bạn đã thay đổi gì để biến nó thành bảng?
Enrico

@Enrico và những người khác có thể tự hỏi về điều tương tự. nikolay đã thay đổi câu trả lời của mình bằng gợi ý schoetbis. Bằng cách di chuyển ngày đầu tiên luôn luôn có cùng độ dài, kết quả có vẻ nhiều bảng hơn.
John

83

Đây là một lệnh đơn giản liệt kê tất cả các nhánh với các cam kết mới nhất:

git branch -v

Để đặt hàng theo cam kết gần đây nhất, hãy sử dụng

git branch -v --sort=committerdate

Nguồn: http://git-scm.com/book/en/Git-Branching-Branch-Quản lý


11
git branch -avnếu bạn muốn xem các chi nhánh không phải địa phương quá.
Scott Stafford

34
Điều này không sắp xếp theo ngày cam kết theo câu hỏi.
Cas

1
Có dễ dàng để git branch -vbao gồm ngày của mỗi cam kết được liệt kê?
dumbledad

1
Làm thế nào về <pre> git chi nhánh -v --sort = committerdate </ pre>?
iraj jelodari

2
Điều này thật tuyệt. Tôi thích git branch -va --sort=-committerdatehiển thị các chi nhánh không phải địa phương, với các chi nhánh được thay đổi gần đây nhất ở đầu.
Clinton Blackmore

61

Tôi sử dụng bí danh sau:

recent = "!r(){git for-each-ref --sort=-committerdate refs/heads --format='%(HEAD)%(color:yellow)%(refname:short)|%(color:bold green)%(committerdate:relative)|%(color:blue)%(subject)|%(color:magenta)%(authorname)%(color:reset)'|column -ts'|'}; r"

sản xuất:

Kết quả

Sử dụng '|' tách.


1
Bí danh tuyệt vời! Tôi sẽ đề xuất column -ts'|'và ký tự ống dẫn nếu dấu phẩy có thể xảy ra bên trong dấu thời gian tương đối trong miền địa phương của bạn.
Bjorn Lindqvist

1
bí danh tuyệt vời, cảm ơn bạn rất nhiều. bạn có thể cải thiện nó để hiển thị nhánh hiện tại với màu khác hoặc với * ở đầu không?
elhadi dp ıpɐɥ ן

2
Ít nhất là trong phiên bản mới nhất của git, bạn chỉ có thể thêm '%(HEAD) ...'vào lúc bắt đầu chuỗi định dạng để có được hiệu ứng tương tự mà không cần chuyển qua sedlệnh
Joshua Skrzypek

5
Tôi không thể git cái này để làm việc như một bí danh git. Tôi đã phải sử dụng[alias] recent = !git for-each-ref --sort=-committerdate refs/heads --format='%(HEAD)%(color:yellow)%(refname:short)|%(color:bold green)%(committerdate:relative)|%(color:blue)%(subject)|%(color:magenta)%(authorname)%(color:reset)'|column -ts'|'
Wesley Smith

11
Tôi đã phải thêm --color = luôn để có được màu sắc. git for-each-ref --sort=-committerdate refs/heads --format='%(HEAD)%(color:yellow)%(refname:short)|%(color:bold green)%(committerdate:relative)|%(color:blue)%(subject)|%(color:magenta)%(authorname)%(color:reset)' --color=always|column -ts'|'}
dùng3342930

40

Tôi đã có thể tham khảo các ví dụ trước để tạo ra thứ gì đó phù hợp nhất với mình.

git for-Each-ref --sort = -committerdate refs / Heads / --format = '% (authordate: short)% (color: red)% (objectname: short)% (color: yellow)% (refname: short )% (màu: đặt lại) (% (màu: xanh)% (committerdate: tương đối)% (màu: đặt lại)) '

Ảnh chụp màn hình của đầu ra


1
Điều đó trông đẹp, nhiều màu sắc hơn so với việc sử dụng chi nhánh git trực tiếp như tôi đã đề xuất trong stackoverflow.com/a/33163401/6309 . +1
VonC

2
Cái này hoạt động tốt cho tôi, không giống như một số khác, vì vậy tôi đã bỏ phiếu cho nó.
Casey

1
Làm việc như là thực sự độc đáo! Cảm ơn! :-)
FrozenTarzan

1
Ditto - cái này hoạt động vượt trội, không giống như một số cái khác tôi vừa thử. Cảm ơn.
Dan Nissenbaum

2
Cái này sạch sẽ và gọn gàng. Thỉnh thoảng tôi sẽ thêm điều khiển từ xa và authorname như sau: git for-each-ref --sort=-committerdate refs/heads/ refs/remotes --format='%(authordate:short) %(authorname) %(color:red)%(objectname:short) %(color:yellow)%(refname:short)%(color:reset) (%(color:green)%(committerdate:relative)%(color:reset))'
ywu

38

Tôi cũng cần màu sắc, thẻ và tham chiếu từ xa mà không có bất kỳ sự trùng lặp nào:

for ref in $(git for-each-ref --sort=-committerdate --format="%(refname)" refs/heads/ refs/remotes ); do git log -n1 $ref --pretty=format:"%Cgreen%cr%Creset %C(yellow)%d%Creset %C(bold blue)<%an>%Creset%n" | cat ; done | awk '! a[$0]++'

Bởi vì trích dẫn có thể khó, đây là bí danh cho Bash:

alias glist='for ref in $(git for-each-ref --sort=-committerdate --format="%(refname)" refs/heads/ refs/remotes ); do git log -n1 $ref --pretty=format:"%Cgreen%cr%Creset %C(yellow)%d%Creset %C(bold blue)<%an>%Creset%n" | cat ; done | awk '"'! a["'$0'"]++'"

$ <lệnh của bạn ở đây> awk: lỗi cú pháp gần dòng 1 awk: bảo lãnh gần dòng 1
Jamie Mason

@GotNoSugarBaby Bạn đang sử dụng dấu ngoặc đơn như ví dụ phải không? bạn đang sử dụng vỏ nào? Bash cho nhân vật đó một ý nghĩa đặc biệt khác.
estani

này, tôi đã chạy cái này trên / bin / bash (GNU bash, phiên bản 4.0.28 (1) -release (i386-pc-solaris2.11)) với một bản sao thẳng và dán ví dụ của bạn - nhưng từ đó tôi đã chạy nó trên / bin / bash (GNU bash, phiên bản 3.2.48 (1) -release (x86_64-apple-darwin12)) và nó hoạt động, vì vậy tôi sẽ xóa bỏ phiếu bầu. Cảm ơn rất nhiều estani.
Jamie Mason

@GotNoSugarBaby Tôi sử dụng 4.2.25 (1) -release (x86_64-pc-linux-gnu) nad đã thử trên 3.x và hoạt động. Tôi không chắc đó là vấn đề gì ... nhưng nó có thể có một vấn đề liên quan đến phiên bản git, thay vì một bash. Trong mọi trường hợp, tôi rất vui vì nó hiệu quả với bạn!
estani

1
@MichaelDiscenza chỉ cần đặt mọi thứ lên đầu. đó sẽ là thêm | head -n20vào cuối. Nếu bạn đang sử dụng bí danh, hãy chắc chắn rằng điều này nằm trong dấu ngoặc kép.
estani

24

Các câu trả lời khác dường như không cho phép vượt qua -vvđể có được đầu ra dài dòng.

Vì vậy, đây là một lớp lót sắp xếp git branch -vvtheo ngày cam kết, giữ màu vv:

git branch -vv --color=always | while read; do echo -e $(git log -1 --format=%ct $(echo "_$REPLY" | awk '{print $2}' | perl -pe 's/\e\[?.*?[\@-~]//g') 2> /dev/null || git log -1 --format=%ct)"\t$REPLY"; done | sort -r | cut -f 2

Nếu bạn muốn in thêm ngày cam kết, bạn có thể sử dụng phiên bản này thay thế:

git branch -vv --color=always | while read; do echo -e $(git log -1 --format=%ci $(echo "_$REPLY" | awk '{print $2}' | perl -pe 's/\e\[?.*?[\@-~]//g') 2> /dev/null || git log -1 --format=%ci)" $REPLY"; done | sort -r | cut -d ' ' -f -1,4-

Đầu ra mẫu:

2013-09-15   master                  da39a3e [origin/master: behind 7] Some patch
2013-09-11 * (detached from 3eba4b8) 3eba4b8 Some other patch
2013-09-09   my-feature              e5e6b4b [master: ahead 2, behind 25] WIP

Có lẽ dễ đọc hơn được chia thành nhiều dòng:

git branch -vv --color=always | while read; do
    # The underscore is because the active branch is preceded by a '*', and
    # for awk I need the columns to line up. The perl call is to strip out
    # ansi colors; if you don't pass --color=always above you can skip this
    local branch=$(echo "_$REPLY" | awk '{print $2}' | perl -pe 's/\e\[?.*?[\@-~]//g')
    # git log fails when you pass a detached head as a branch name.
    # Hide the error and get the date of the current head.
    local branch_modified=$(git log -1 --format=%ci "$branch" 2> /dev/null || git log -1 --format=%ci)
    echo -e "$branch_modified $REPLY"
# cut strips the time and timezone columns, leaving only the date
done | sort -r | cut -d ' ' -f -1,4-

Điều này cũng sẽ hoạt động với các đối số khác git branch, ví dụ như -vvrđể liệt kê các nhánh theo dõi từ xa hoặc -vvaliệt kê cả các nhánh theo dõi từ xa và các nhánh cục bộ.


-vvthực sự có thể hữu ích, cảm ơn. Tuy nhiên, giải pháp này vẫn sinh ra các quy trình mới cho mỗi chi nhánh mà OP muốn tránh.
musiphil

Trên thực tế git branchkhông xác định cụ thể ý nghĩa của -vv, nhưng chỉ của -v, vì vậy -vvnên có cùng ý nghĩa -v.
musiphil

2
Đây là thứ tốt nhất. Và thêm -avv làm cho nó cũng tính đến các chi nhánh từ xa. Cám ơn vì cái này!
Gopherkhan

@musiphil Trang web chi nhánh git của tôi , phần -v, -vv, --verbosechứa các mục sau:If given twice, print the name of the upstream branch, as well
Perleone

@Perleone: Tôi không biết làm thế nào tôi có được thông tin đó, nhưng bạn đã đúng và tôi đã sửa chữa. Cảm ơn!
musiphil

23

git 2.7 (Q4 2015) sẽ giới thiệu phân loại chi nhánh bằng cách sử dụng trực tiếp git branch:
Xem cam kết aa3bc55 , cam kết aedcb7d , cam kết 1511b22 , cam kết f65f139 , ... (23 tháng 9 năm 2015), cam kết aedcb7d , cam kết 1511b22 , cam kết ca41799 (24 tháng 9 năm 2015) cam kết f65f139 , ... (23 tháng 9 năm 2015) bởi Karthik Nayak ( KarthikNayak) .
(Được hợp nhất bởi Junio ​​C Hamano - gitster- trong cam kết 7f11b48 , ngày 15 tháng 10 năm 2015)

Cụ thể, cam kết aedcb7d :

branch.c: sử dụng ref-filterAPI ''

Tạo API ' branch.c' sử dụng ' ref-filter' để lặp qua sắp xếp ref. Điều này loại bỏ hầu hết các mã được sử dụng trong ' branch.c' thay thế nó bằng các cuộc gọi đến ref-filterthư viện ''.

thêm tùy chọn--sort=<key> :

Sắp xếp dựa trên khóa đã cho.
Tiền tố -để sắp xếp theo thứ tự giảm dần của giá trị.

Bạn có thể sử dụng --sort=<key>tùy chọn nhiều lần, trong trường hợp đó, khóa cuối cùng trở thành khóa chính.

Các phím được hỗ trợ giống như cácgit for-each-ref phím trong .
Sắp xếp thứ tự mặc định để sắp xếp dựa trên tên đầy đủ (bao gồm refs/...tiền tố). Danh sách này tách ra ĐẦU (nếu có) trước, sau đó là các nhánh cục bộ và cuối cùng là các nhánh theo dõi từ xa.

Đây:

git branch --sort=-committerdate 

Hoặc (xem bên dưới với Git 2.19)

# if you are sure to /always/ want to see branches ordered by commits:
git config --global branch.sort -committerdate
git branch

Xem thêm cam kết 9e46833 (30 tháng 10 năm 2015) bởi Karthik Nayak ( KarthikNayak) .
Giúp đỡ: Junio ​​C Hamano ( gitster) .
(Được hợp nhất bởi Junio ​​C Hamano - gitster- trong cam kết 415095f , ngày 03 tháng 11 năm 2015)

Khi sắp xếp theo giá trị số (ví dụ --sort=objectsize), không có so sánh dự phòng khi cả hai ref đều giữ cùng một giá trị. Điều này có thể gây ra kết quả không mong muốn (nghĩa là thứ tự của danh sách giới thiệu có giá trị bằng nhau không thể được xác định trước) như được chỉ ra bởi Johannes Sixt ( $ gmane / 280117 ).

Do đó, dự phòng so sánh bảng chữ cái dựa trên tên gọi bất cứ khi nào tiêu chí khác bằng nhau .

$ git branch --sort=objectsize

*  (HEAD detached from fromtag)
      branch-two
      branch-one
      master

Với Git 2.19, thứ tự sắp xếp có thể được đặt theo mặc định.
git branchhỗ trợ một cấu hình branch.sort, như git tag, đã có một cấu hình tag.sort.
Xem cam kết 560ae1c (16 tháng 8 năm 2018) của Samuel Maftoul (``) .
(Được hợp nhất bởi Junio ​​C Hamano - gitster- trong cam kết d89db6f , ngày 27 tháng 8 năm 2018)

branch.sort:

Biến này kiểm soát thứ tự sắp xếp của các nhánh khi được hiển thị bởi git-branch.
Nếu không có --sort=<value>tùy chọn "" được cung cấp, giá trị của biến này sẽ được sử dụng làm mặc định.


Để liệt kê các chi nhánh từ xa, sử dụng git branch -r --sort=objectsize. Các -rlá cờ gây ra nó để liệt kê các chi nhánh từ xa thay vì các chi nhánh địa phương.


Với Git 2.27 (quý 2 năm 2020), git branchcác for-each-refbiến thể " " và các " " khác đã chấp nhận nhiều --sort=<key>tùy chọn theo thứ tự ưu tiên ngày càng tăng, nhưng nó đã có một vài phá vỡ xung quanh việc --ignore-casexử lý "" và phá vỡ liên kết với tên gọi đã được sửa.

Xem cam kết 7c5045f , cam kết 76f9e56 (03 tháng 5 năm 2020) của Jeff King ( peff) .
(Được hợp nhất bởi Junio ​​C Hamano - gitster- trong cam kết 6de1630 , ngày 08 tháng 5 năm 2020)

ref-filter: chỉ áp dụng sắp xếp tên dự phòng sau khi tất cả các loại người dùng

Đã ký: Jeff King

Cam kết 9e468334b4 (" ref-filter: dự phòng so sánh theo thứ tự chữ cái", 2015-10-30, Git v2.7.0-rc0 - hợp nhất được liệt kê trong lô # 10 ) đã dạy cách sắp xếp bộ lọc ref để so sánh các tên gọi.
Nhưng nó đã làm sai ở cấp độ, ghi đè kết quả so sánh cho một --sortkhóa " " duy nhất từ người dùng, thay vì sau khi tất cả các khóa sắp xếp đã hết.

Điều này hoạt động chính xác cho một --sorttùy chọn "", nhưng không phải cho nhiều người.
Chúng tôi sẽ phá vỡ bất kỳ mối quan hệ nào trong khóa đầu tiên bằng tên gọi và không bao giờ đánh giá khóa thứ hai.

Để làm cho vấn đề thậm chí thú vị hơn, đôi khi chúng tôi chỉ áp dụng dự phòng này!
Đối với một trường như " taggeremail" yêu cầu so sánh chuỗi, chúng tôi thực sự trả về kết quả strcmp(), ngay cả khi là 0.
Nhưng đối với các valuetrường "" như " taggerdate", chúng tôi đã áp dụng dự phòng. Và đó là lý do tại sao bài kiểm tra nhiều loại của chúng tôi đã bỏ lỡ điều này: nó sử dụng taggeremaillàm so sánh chính.

Vì vậy, hãy bắt đầu bằng cách thêm một bài kiểm tra nghiêm ngặt hơn nhiều. Chúng tôi sẽ có một bộ các cam kết thể hiện mọi sự kết hợp của hai email, ngày và tên họ. Sau đó, chúng tôi có thể xác nhận rằng sắp xếp của chúng tôi được áp dụng với quyền ưu tiên chính xác và chúng tôi sẽ nhấn cả hai bộ so sánh chuỗi và giá trị.

Điều đó cho thấy lỗi và cách khắc phục rất đơn giản: di chuyển dự phòng sang compare_refs()chức năng bên ngoài , sau khi tất cả ref_sortingcác khóa đã hết.

Lưu ý rằng trong chức năng bên ngoài, chúng ta không có "ignore_case"cờ, vì đó là một phần của từng thành ref_sortingphần riêng lẻ . Thật đáng tranh luận là một dự phòng như vậy nên làm gì, vì chúng tôi đã không sử dụng các khóa của người dùng để khớp.
Nhưng cho đến bây giờ chúng tôi đã cố gắng tôn trọng lá cờ đó, vì vậy điều ít xâm lấn nhất là cố gắng tiếp tục làm như vậy.
Vì tất cả người gọi trong mã hiện tại đều đặt cờ cho tất cả các phím hoặc không có gì, chúng tôi chỉ có thể kéo cờ từ phím đầu tiên. Trong một thế giới giả thuyết nơi người dùng thực sự có thể lật các trường hợp không nhạy cảm của các khóa, chúng tôi có thể muốn mở rộng mã để phân biệt trường hợp đó với chăn " --ignore-case".


Để liệt kê các điều khiển từ xa với tùy chọn này, hãy thêm-r
Troy Daniels

@TroyDaniels Đồng ý. Bạn có thể chỉnh sửa câu trả lời. Tôi sẽ xem lại chỉnh sửa của bạn.
VonC

19

Tôi thích sử dụng một ngày tương đối và rút ngắn tên chi nhánh như thế này:

git for-each-ref --sort='-authordate:iso8601' --format=' %(authordate:relative)%09%(refname:short)' refs/heads

Cung cấp cho bạn đầu ra:

21 minutes ago  nathan/a_recent_branch
6 hours ago     master
27 hours ago    nathan/some_other_branch
29 hours ago    branch_c
6 days ago      branch_d

Tôi khuyên bạn nên tạo một tệp Bash để thêm tất cả các bí danh yêu thích của bạn và sau đó chia sẻ tập lệnh ra cho nhóm của bạn. Đây là một ví dụ để thêm chỉ cái này:

#!/bin/sh

git config --global alias.branches "!echo ' ------------------------------------------------------------' && git for-each-ref --sort='-authordate:iso8601' --format=' %(authordate:relative)%09%(refname:short)' refs/heads && echo ' ------------------------------------------------------------'"

Sau đó, bạn chỉ có thể làm điều này để có được một danh sách chi nhánh địa phương được định dạng và sắp xếp độc đáo:

git branches

Cập nhật: Làm điều này nếu bạn muốn tô màu:

#!/bin/sh
#
(echo ' ------------------------------------------------------------‌​' && git for-each-ref --sort='-authordate:iso8601' --format=' %(authordate:relative)%09%(refname:short)' refs/heads && echo ' ------------------------------------------------------------‌​') | grep --color -E "$(git rev-parse --abbrev-ref HEAD)$|$"

Điều này mang lại cho tôifatal: unknown field name: '-authordate:iso8601'
Nhân tố huyền bí

1
Đầu ra màu sắc lạ mắt là lạ mắt, nhưng đây là đơn giản và chỉ là những gì tôi đang tìm kiếm. Thay thế refs/headsbằng refs/remotesđể có một cái nhìn vào các chi nhánh từ xa.
Lambart

Bản thân lệnh này rất đáng yêu, nhưng bí danh đã gây ra lỗi:expansion of alias 'branches' failed; 'echo' is not a git command
Philip Kahn

Làm việc cho tôi. Điều gì xảy ra nếu bạn chỉ sao chép dán vào thiết bị đầu cuối? (echo ' ------------------------------------------------------------‌​' && git for-each-ref --sort='-authordate:iso8601' --format=' %(authordate:relative)%09%(refname:short)' refs/heads && echo ' ------------------------------------------------------------‌​') | grep --color -E "$(git rev-parse --abbrev-ref HEAD)$|$"
n8tr

17

Kể từ Git 2.19, bạn có thể chỉ cần:

git branch --sort=-committerdate

Bạn cũng có thể:

git config branch.sort -committerdate

Vì vậy, bất cứ khi nào bạn liệt kê các nhánh trong kho lưu trữ hiện tại, nó sẽ được liệt kê được sắp xếp theo committerdate.

Nếu bất cứ khi nào bạn liệt kê các nhánh, bạn muốn chúng được sắp xếp theo comitterdate:

git config --global branch.sort -committerdate

Tuyên bố miễn trừ trách nhiệm: Tôi là tác giả của tính năng này trong Git và tôi đã triển khai nó khi tôi thấy câu hỏi này.


2
Câu trả lời cập nhật nhất, dễ dàng hơn nhiều so với sử dụng các tập lệnh hoặc bí danh phức tạp 👌
mtefi

Sử dụng cẩn thận! Hãy coi chừng mọi người, đây không phải là một lệnh để liệt kê các nhánh. Đó là một lệnh để thay đổi cấu hình của Git và sẽ có hậu quả toàn cầu vĩnh viễn.
Jazimov

1
@Jazimov bạn nói đúng, tôi đã chỉnh sửa câu trả lời để nó rõ ràng hơn
user801247

11

Thêm một số màu (vì pretty-formatkhông có sẵn)

[alias]
    branchdate = for-each-ref --sort=-committerdate refs/heads/ --format="%(authordate:short)%09%(objectname:short)%09%1B[0;33m%(refname:short)%1B[m%09"

9

Tôi có cùng một vấn đề, vì vậy tôi đã viết một viên ngọc Ruby tên là Twig . Nó liệt kê các nhánh theo thứ tự thời gian (mới nhất trước) và cũng có thể cho phép bạn đặt tuổi tối đa để bạn không liệt kê tất cả các nhánh (nếu bạn có nhiều nhánh). Ví dụ:

$ twig

                              issue  status       todo            branch
                              -----  ------       ----            ------
2013-01-26 18:00:21 (7m ago)  486    In progress  Rebase          optimize-all-the-things
2013-01-26 16:49:21 (2h ago)  268    In progress  -               whitespace-all-the-things
2013-01-23 18:35:21 (3d ago)  159    Shipped      Test in prod  * refactor-all-the-things
2013-01-22 17:12:09 (4d ago)  -      -            -               development
2013-01-20 19:45:42 (6d ago)  -      -            -               master

Nó cũng cho phép bạn lưu trữ các thuộc tính tùy chỉnh cho từng chi nhánh, ví dụ: id vé, trạng thái, mã thông báo và lọc danh sách các chi nhánh theo các thuộc tính này. Thông tin thêm: http://rondevera.github.io/twig/


5
Cái tên đó có thể không giúp ích gì vì tôi khá chắc chắn rằng có một vài phần mềm ngoài kia có cùng tên.
ngực

8

Tôi đã đưa ra lệnh sau (cho Git 2.13 trở lên):

git branch -r --sort=creatordate \
    --format "%(creatordate:relative);%(committername);%(refname:lstrip=-1)" \
    | grep -v ";HEAD$" \
    | column -s ";" -t

Nếu bạn không có, columnbạn có thể thay thế dòng cuối cùng bằng

    | sed -e "s/;/\t/g"

Đầu ra trông như

6 years ago             Tom Preston-Werner  book
4 years, 4 months ago   Parker Moore        0.12.1-release
4 years ago             Matt Rogers         1.0-branch
3 years, 11 months ago  Matt Rogers         1.2_branch
3 years, 1 month ago    Parker Moore        v1-stable
12 months ago           Ben Balter          pages-as-documents
10 months ago           Jordon Bedwell      make-jekyll-parallel
6 months ago            Pat Hawks           to_integer
5 months ago            Parker Moore        3.4-stable-backport-5920
4 months ago            Parker Moore        yajl-ruby-2-4-patch
4 weeks ago             Parker Moore        3.4-stable
3 weeks ago             Parker Moore        rouge-1-and-2
19 hours ago            jekyllbot           master

Tôi đã viết một bài blog về cách các phần khác nhau hoạt động.


Đẹp. +1. Nó không sử dụng git branch --sorttôi đã đề cập trong stackoverflow.com/a/33163401/6309 .
VonC

@DanNissenbaum Đảm bảo bạn đang sử dụng Git 2.13 (phát hành vào tháng 5 năm 2017) trở lên.
bdesham


5

Đây là một đoạn script nhỏ mà tôi sử dụng để chuyển đổi giữa các nhánh gần đây:

#!/bin/bash
# sudo bash

re='^[0-9]+$'

if [[ "$1" =~ $re ]]; then
    lines="$1"
else
    lines=10
fi
branches="$(git recent | tail -n $lines | nl)"
branches_nf="$(git recent-nf | tail -n $lines | nl)"
echo "$branches"

# Prompt which server to connect to
max="$(echo "$branches" | wc -l)"
index=
while [[ ! ( "$index" =~ ^[0-9]+$ && "$index" -gt 0 && "$index" -le "$max" ) ]]; do
    echo -n "Checkout to: "
    read index
done

branch="$( echo "$branches_nf" | sed -n "${index}p" | awk '{ print $NF }' )"
git co $branch
clear

Sử dụng hai bí danh đó:

recent = for-each-ref --sort=committerdate refs/heads/ --format=' %(color:blue) %(authorname) %(color:yellow)%(refname:short)%(color:reset)'
recent-nf = for-each-ref --sort=committerdate refs/heads/ --format=' %(authorname) %(refname:short)'

Chỉ cần gọi nó trong kho Git, và nó sẽ hiển thị cho bạn các nhánh N cuối cùng (10 theo mặc định) và một số dành cho mỗi bên. Nhập số của chi nhánh và kiểm tra xem:

Nhập mô tả hình ảnh ở đây


4

Thông thường chúng tôi xem xét các chi nhánh từ xa gần đây. Hãy thử cái này

git fetch
git for-each-ref --sort=-committerdate refs/remotes/origin

4

Đây là một kịch bản khác làm những gì tất cả các kịch bản khác làm. Trong thực tế, nó cung cấp một chức năng cho vỏ của bạn.

Đóng góp của nó là nó lấy một số màu từ cấu hình Git của bạn (hoặc sử dụng mặc định).

# Git Branch by Date
# Usage: gbd [ -r ]
gbd() {
    local reset_color=`tput sgr0`
    local subject_color=`tput setaf 4 ; tput bold`
    local author_color=`tput setaf 6`

    local target=refs/heads
    local branch_color=`git config --get-color color.branch.local white`

    if [ "$1" = -r ]
    then
        target=refs/remotes/origin
        branch_color=`git config --get-color color.branch.remote red`
    fi

    git for-each-ref --sort=committerdate $target --format="${branch_color}%(refname:short)${reset_color} ${subject_color}%(subject)${reset_color} ${author_color}- %(authorname) (%(committerdate:relative))${reset_color}"
}

3

Điều này dựa trên phiên bản của saeedgnu , nhưng với nhánh hiện tại được hiển thị với một ngôi sao và màu sắc, và chỉ hiển thị bất cứ thứ gì không được mô tả là "tháng" hoặc "năm" trước:

current_branch="$(git symbolic-ref --short -q HEAD)"
git for-each-ref --sort=committerdate refs/heads \
  --format='%(refname:short)|%(committerdate:relative)' \
  | grep -v '\(year\|month\)s\? ago' \
  | while IFS='|' read branch date
    do
      start='  '
      end=''
      if [[ $branch = $current_branch ]]; then
        start='* \e[32m'
        end='\e[0m'
      fi
      printf "$start%-30s %s$end\\n" "$branch" "$date"
    done

2

Kết quả tốt nhất của tôi là một kịch bản:

git for-each-ref --sort=-committerdate refs/heads/ --format='%(refname:short)|%(committerdate:iso)|%(authorname)' |
    sed 's/refs\/heads\///g' |
    grep -v BACKUP  | 
    while IFS='|' read branch date author
    do 
        printf '%-15s %-30s %s\n' "$branch" "$date" "$author"
    done

1
Những loại kịch bản? Bash?
Peter Mortensen

2

git branch --sort=-committerdate | head -5

Đối với bất kỳ ai quan tâm đến việc chỉ nhận được 5 tên chi nhánh hàng đầu được sắp xếp dựa trên ngày giao dịch.



1

Đây là biến thể tôi đang tìm kiếm:

git for-each-ref --sort=-committerdate --format='%(committerdate)%09%(refname:short)' refs/heads/ | tail -r

Điều đó tail -rđảo ngược danh sách để gần đây nhất commiterdatelà cuối cùng.


3
Bạn cũng có thể thay đổi --sort = -committerdate thành --sort = committerdate để thực hiện điều này.
phát lại

Cái nào tail-r?
Christoffer Hammarström

1

Tôi chuyển đầu ra từ câu trả lời được chấp nhận vào dialog, để đưa cho tôi một danh sách tương tác:

#!/bin/bash

TMP_FILE=/tmp/selected-git-branch

eval `resize`
dialog --title "Recent Git Branches" --menu "Choose a branch" $LINES $COLUMNS $(( $LINES - 8 )) $(git for-each-ref --sort=-committerdate refs/heads/ --format='%(refname:short) %(committerdate:short)') 2> $TMP_FILE

if [ $? -eq 0 ]
then
    git checkout $(< $TMP_FILE)
fi

rm -f $TMP_FILE

clear

Lưu dưới dạng (ví dụ) ~/bin/git_recent_branches.shchmod +xnó. Sau đó git config --global alias.rb '!git_recent_branches.sh'để cho tôi một git rblệnh mới .


1

Tôi biết đã có rất nhiều câu trả lời, nhưng đây là hai xu của tôi cho một bí danh đơn giản (tôi muốn có chi nhánh gần đây nhất của mình ở phía dưới):

[alias]
        br = !git branch --sort=committerdate --color=always | tail -n15
[color "branch"]
        current = yellow
        local = cyan
        remote = red

Điều này sẽ cung cấp cho bạn một cái nhìn tổng quan đẹp về 15 nhánh mới nhất của bạn, với màu sắc, với nhánh hiện tại của bạn được tô sáng (và nó có dấu hoa thị).


1

Có một số sự cố khi xử lý các trích dẫn đơn trên Mac trong bash_profile khi cố gắng đặt bí danh. Câu trả lời này đã giúp giải quyết nó " Cách thoát các trích dẫn đơn trong các chuỗi được trích dẫn

Giải pháp làm việc:

alias gb='git for-each-ref --sort=committerdate refs/heads/ --format='"'"'%(HEAD) %(color:yellow)%(refname:short)%(color:reset) - %(color:red)%(objectname:short)%(color:reset) - %(contents:subject) - %(authorname) (%(color:green)%(committerdate:relative)%(color:reset))'"'"''

PS không thể bình luận vì danh tiếng của tôi


0

git for-each-ref --sort=committerdate refs/heads/ --format='%(HEAD) %(color:yellow)%(refname:short)%(color:reset) - %(color:red)%(objectname:short)%(color:reset) - %(contents:subject) - %(authorname) (%(color:green)%(committerdate:relative)%(color:reset))' đây là thứ bạn cần


0

Git v2.19 giới thiệu branch.sorttùy chọn cấu hình (xem Branch.sort ).

Vì vậy, git branchsẽ sắp xếp theo ngày committer (desc) theo mặc định với

# gitconfig
[branch]
    sort = -committerdate     # desc

kịch bản:

$ git config --global branch.sort -committerdate

Cập nhật:

Vì thế,

$ git branch
* dev
  master
  _

$ git branch -v
* dev    0afecf5 Merge branch 'oc' into dev
  master 652428a Merge branch 'dev'
  _      7159cf9 Merge branch 'bashrc' into dev
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.