可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I found the below script that lists the branches by date. How do I filter this to exclude newer branches and feed the results into the Git delete command?
for k in $(git branch | sed /\*/d); do
echo "$(git log -1 --pretty=format:"%ct" $k) $k"
done | sort -r | awk '{print $2}'
回答1:
How about using --since
and --before
?
For example, this will delete all branches that have not received any commits for a week:
for k in $(git branch | sed /\*/d); do
if [ -n "$(git log -1 --since='1 week ago' -s $k)" ]; then
git branch -D $k
fi
done
If you want to delete all branches that are more than a week old, use --before
:
for k in $(git branch | sed /\*/d); do
if [ -n "$(git log -1 --before='1 week ago' -s $k)" ]; then
git branch -D $k
fi
done
Be warned though that this will also delete branches that where not merged into master or whatever the checked out branch is.
回答2:
The poor man's method:
List the branches by date of last commit:
git branch --sort=committerdate | xargs echo
this will list the branches while xargs echo
command makes it inline (thx Jesse).
You will see all your branches with old ones at the beginning:
1_branch 2_branch 3_branch 4_branch
Copy the first n ones, which are outdated and paste at the end of the batch delete command:
git branch -D 1_branch 2_branch
This will delete the selected ones only, so you have more control over the process.
To list the branches by creation date, use the --sort=authordate:iso8601
command as suggested by Amy
回答3:
It's something similar to Daniel Baulig answer, but also takes in consideration ben's comment. Also It filters branches by a given patter, since we're using try-XX convention for branching.
for k in $(git branch -r | awk -F/ '/\/YOUR_PREFIX_HERE/{print $2}' | sed /\*/d); do
if [ -z "$(git log -1 --since='Jul 31, 2015' -s origin/$k)" ]; then
echo deleting "$(git log -1 --pretty=format:"%ct" origin/$k) origin/$k";
git push origin --delete $k;
fi;
done
回答4:
This is what worked for me:
for k in $(git branch -r | sed /\*/d); do
if [ -z "$(git log -1 --since='Aug 10, 2016' -s $k)" ]; then
branch_name_with_no_origin=$(echo $k | sed -e "s/origin\///")
echo deleting branch: $branch_name_with_no_origin
git push origin --delete $branch_name_with_no_origin
fi
done
The crucial part is that the branch name (variable $k) contains the /origin/
part eg origin/feature/my-cool-new-branch
However, if you try to git push --delete, it'll fail with an error like:
unable to delete 'origin/feature/my-cool-new-branch': remote ref does not exist.
So we use sed to remove the /origin/
part so that we are left with a branch name like feature/my-cool-new-branch
and now git push --delete will work.
回答5:
I'm assuming that you want to delete just the refs, not the commits in the branches. To delete all merged branches except the most recent __X__
:
git branch -d `for k in $(git branch | sed /\*/d); do
echo "$(git log -1 --pretty=format:"%ct" $k) $k"
done | sort -r | awk 'BEGIN{ORS=" "}; {if(NR>__X__) print $2}'`
To delete all branches before timestamp __Y__
:
git branch -d `for k in $(git branch | sed /\*/d); do
echo "$(git log -1 --pretty=format:"%ct" $k) $k"
done | sort -r | awk 'BEGIN{ORS=" "}; {if($1<__Y__) print $2}'`
Replace the -d
option by -D
if you want to delete branches that haven't been merged as well... but be careful, because that will cause the dangling commits to be garbage-collected at some point.
回答6:
The above code did not work for me, but it was close. Instead, I used the following:
for k in $(git branch | sed /\*/d); do
if [[ ! $(git log -1 --since='2 weeks ago' -s $k) ]]; then
git branch -D $k
fi
done
回答7:
Based on @daniel-baulig's answer and the comments I came up with this:
for k in $(git branch -r --format="%(refname:short)" | sed s#^origin/##); do
if [ -z "$(git log -1 --since='4 week ago' -s $k)" ]; then
## Info about the branches before deleting
git log -1 --format="%ci %ce - %H $k" -s $k;
## Delete from the remote
git push origin --delete $k;
## Delete the local branch, regardless of whether it's been merged or not
git branch -D $k
fi;
done
This can be used to delete all old branches (merged or NOT).
The motivation for doing so is that it is unlikely that branches that has not been touched in a month rot and never make it to master. Naturally, the timeframe for pruning old branches depends on how fast the master branch moves.
回答8:
Safe way to show the delete commands only for local branches merged into master with the last commit over a month ago.
for k in $(git branch --format="%(refname:short)" --merged master); do
if (($(git log -1 --since='1 month ago' -s $k|wc -l)==0)); then
echo git branch -d $k
fi
done
This does nothing but to output something like:
git branch -d issue_3212
git branch -d fix_ui_search
git branch -d issue_3211
Which I copy and paste directly (remove the echo to delete it directly)
This is very safe.