Listing each branch and its last revision's da

2019-01-08 03:09发布

I need to delete old and unmaintained branches from our remote repo. I'm trying to find a way with which to list the remote branches by their last modified date, and I can't.

Does someone know of an easy way to list remote branches this way?

10条回答
Emotional °昔
2楼-- · 2019-01-08 03:42

Here is what I use:

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

This is the output:

2014-01-22 11:43:18 +0100       refs/heads/master
2014-01-22 11:43:18 +0100       refs/heads/a
2014-01-17 12:34:01 +0100       refs/heads/b
2014-01-14 15:58:33 +0100       refs/heads/maint
2013-12-11 14:20:06 +0100       refs/heads/d/e
2013-12-09 12:48:04 +0100       refs/heads/f

For remote branches, just use "refs/remotes" instead of "refs/heads":

git for-each-ref --sort='-committerdate:iso8601' --format=' %(committerdate:iso8601)%09%(refname)' refs/remotes

You may want to call "git fetch --prune" before to have the latest information.

查看更多
Ridiculous、
3楼-- · 2019-01-08 03:43

Here's a function you can add to your bash_profile to make this easier.

Usage when in a git repository:

  • branch prints all local branches
  • branch -r prints all remote branches

Function:

branch() {
   local pattern="s/^..//"
   local arg=""
   if [[ $@ == "-r" ]]; then
      pattern="s/^..(.*?)( ->.*)?$/\1/"
      arg=" -r "
      echo '-r provided'
   fi
   for k in $(git branch $arg | perl -pe "$pattern"); do
      echo -e $(git show --pretty=format:"%Cgreen%ci %Cblue%cr%Creset" $k -- | head -n 1)\\t$k
   done | sort -r
}
查看更多
唯我独甜
4楼-- · 2019-01-08 03:44

Here is what I came up with after also reviewing this.

for REF in $(git for-each-ref --sort=-committerdate --format="%(objectname)" \
    refs/remotes refs/heads)
do
    if [ "$PREV_REF" != "$REF" ]; then
        PREV_REF=$REF
        git log -n1 $REF --date=short \
            --pretty=format:"%C(auto)%ad %h%d %s %C(yellow)[%an]%C(reset)"
    fi
done

The PREV_REF check is to remove duplicates if more than one branch points to the same commit. (As in local branch that exist in the remote as well.)

NOTE that per the OP request, git branch --merged and git branch --no-merged are useful in identifying which branches can be easily deleted. [https://git-scm.com/docs/git-branch]

查看更多
神经病院院长
5楼-- · 2019-01-08 03:45

Sorted remote branches and the last commit date for each branch.

for branch in `git branch -r | grep -v HEAD`;do echo -e `git show --format="%ci %cr" $branch | head -n 1` \\t$branch; done | sort -r
查看更多
叛逆
6楼-- · 2019-01-08 03:47

I made two variants, based on VonC's answer.

My first variant:

for k in `git branch -a | sed -e s/^..// -e 's/(detached from .*)/HEAD/'`; do echo -e `git log -1 --pretty=format:"%Cgreen%ci |%Cblue%cr |%Creset$k |%s" $k --`;done | sort | column -t -s "|"

This handles local & remote branches (-a), handles detached-head state (the longer sed command, though the solution is kind of crude -- it just replaces the detached branch info with the keyword HEAD), adds in the commit subject (%s), and puts things into columns via literal pipe characters in the format string and passing the end result to column -t -s "|". (You could use whatever as the separator, as long as it's something you don't expect in the rest of the output.)

My second variant is quite hacky, but I really wanted something that still has an indicator of "this is the branch you're currently on" like the branch command does.

CURRENT_BRANCH=0
for k in `git branch -a | sed -e 's/\*/CURRENT_BRANCH_MARKER/' -e 's/(detached from .*)/HEAD/'`
do
    if [ "$k" == 'CURRENT_BRANCH_MARKER' ]; then
        # Set flag, skip output
        CURRENT_BRANCH=1
    elif [ $CURRENT_BRANCH == 0 ]; then
        echo -e `git log -1 --pretty=format:"%Cgreen%ci |%Cblue%cr |%Creset$k |%s" $k --`
    else
        echo -e `git log -1 --pretty=format:"%Cgreen%ci |%Cblue%cr |%Creset* %Cgreen$k%Creset |%s" $k --`
        CURRENT_BRANCH=0
    fi
done | sort | column -t -s "|"

This turns the * that marks the current branch into a keyword, and when the loop body sees the keyword it instead sets a flag and outputs nothing. The flag is used to indicate that an alternate formatting should be used for the next line. Like I said, totally hacky, but it works! (Mostly. For some reason my last column is getting outdented on the current branch line. But I really should get back to doing actual work instead of tweaking this more.)

查看更多
爷的心禁止访问
7楼-- · 2019-01-08 03:48

Building off of Olivier Croquette, I like using a relative date and shortening the branch name like this:

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

Which gives you output:

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

I recommend making a bash file for adding all your favorite aliases and then sharing the script out to your team. Here's an example to add just this one:

#!/bin/sh

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

Then you can just do this to get a nicely formatted and sorted local branch list:

git branches
查看更多
登录 后发表回答