Git - Automatically fast forward all tracking branches on pull

走远了吗. 提交于 2019-11-30 04:19:32
VonC

But wait:

Note: I suppose you have tracked all your remote branches as in "Track all remote git branches as local branches."


Note: Git 2.0 (Q2 2014) will introduce with commit b814da8 a config push.ff:

pull.ff::

By default, Git does not create an extra merge commit when merging a commit that is a descendant of the current commit. Instead, the tip of the current branch is fast-forwarded.

  • When set to false, this variable tells Git to create an extra merge commit in such a case (equivalent to giving the --no-ff option from the command line).
  • When set to only, only such fast-forward merges are allowed (equivalent to giving the --ff-only option from the command line).

Shell script that fast-forwards all branches that have their upstream branch set to the matching origin/ branch without doing any checkouts

  • it doesn't change your current branch at any time, no need to deal with working copy changes and time lost checking out

  • it only does fast-forwards, branches that cannot be fast-forwarded will show an error message and will be skipped

Make sure all your branches' upstream branches are set correctly by running git branch -vv. Set the upstream branch with git branch -u origin/yourbanchname

Copy-paste into a file and chmod 755:

#!/bin/sh

curbranch=$(git rev-parse --abbrev-ref HEAD)

for branch in $(git for-each-ref refs/heads --format="%(refname:short)"); do
        upbranch=$(git config --get branch.$branch.merge | sed 's:refs/heads/::');
        if [ "$branch" = "$upbranch" ]; then
                if [ "$branch" = "$curbranch" ]; then
                        echo Fast forwarding current branch $curbranch
                        git merge --ff-only origin/$upbranch
                else
                        echo Fast forwarding $branch with origin/$upbranch
                        git fetch . origin/$upbranch:$branch
                fi
        fi
done;

If you really want to fast forward all local branches that are tracking remote branches you might want to consider adding this as an alias to your ~/.gitconfig:

[alias]
    pull-all = !"for b in $(git for-each-ref refs/heads --format='%(refname)') ; do git checkout ${b#refs/heads/} ; git pull --ff-only ; done"

You can then run git pull-all, it will iterate through your local branches and run a git pull --ff-only on each.

The following one-liner fast-forwards all branches that have an upstream branch if possible, and prints an error otherwise:

git branch \
  --format "%(if)%(upstream:short)%(then)git push . %(upstream:short):%(refname:short)%(end)" |
  sh

How does it work?

It uses a custom format with the git branch command. For each branch that has an upstream branch, it prints a line with the following pattern:

git push . <remote-ref>:<branch>

This can be piped directly into sh (assuming that the branch names are well-formed). Omit the | sh to see what it's doing.

Caveat

The currently checked-out branch will not be updated with a message like

! [remote rejected] origin/master -> master (branch is currently checked out)

For this, you can resort to regular git pull --ff-only .

Alias

Add the following to your .gitconfig so that git fft performs this command:

[alias]
        fft = !sh -c 'git branch --format \"%(if)%(upstream:short)%(then)git push . %(upstream:short):%(refname:short)%(end)\" | sh' -

The alias is a shorthand to "fast-forward tracking (branches)".

SmartGit, for example, has an option to automatically merge changes from the tracked branch if you switch to a branch. This should do what you want to achieve.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!