git
,而不是解决任何特定问题。换句话说,“达到相同目的”的替代方法(即绕开标题中的问题)与本题无关。该命令为:
git pull
...应该等价于此序列
git fetch
git merge
你是否能够将 git pull <REMOTE> <BRANCH>
(即使用明确参数的远程和要拉取的分支)分解为类似于fetch
后跟merge
的序列?
我想这个命令中的fetch
部分会很简单。
git fetch <REMOTE> <BRANCH>
...但是,如果这样做,我无法找到正确的git merge ...
命令。
我尝试了一些“显而易见”的方法。例如,如果我运行git branch -r
,输出会在分支列表中列出<REMOTE>/<BRANCH>
,因此我尝试使用git merge -m 'some message' <REMOTE>/<BRANCH>
,但是git
回复说Already up-to-date.
,并且git-log
显示HEAD
保持在尝试git merge
之前的相同提交上。为了确认这一点,我在git fetch ...
和git merge ...
之间加上了git log ...
调用,就像这样:
git log --all --oneline --graph --decorate -10
git fetch <REMOTE> <BRANCH>
git merge -m 'some message' <REMOTE>/<BRANCH>
git log --all --oneline --graph --decorate -10
两个调用
git log ...
生成的输出完全相同,它们都显示本地 <BRANCH>
领先于 <REMOTE>/<BRANCH>
。
以下模拟示例以
/bin/sh
脚本的形式重现了上述结果。(该脚本在 Ubuntu Linux 上测试通过;你的情况可能有所不同。)#!/bin/sh
BASEDIR=/tmp/gittest
REMOTENAME=remrepo
REMOTEURL="$BASEDIR/$REMOTENAME"
BRANCHNAME=test
BRANCHNAME=master
rm -rf $REMOTEURL
mkdir -p $REMOTEURL
rm -rf $BASEDIR/clone1 $BASEDIR/clone2
git init --bare -q $REMOTEURL/.git
git clone -q -o $REMOTENAME $REMOTEURL $BASEDIR/clone1
git clone -q -o $REMOTENAME $REMOTEURL $BASEDIR/clone2
pushd $BASEDIR/clone1 >/dev/null
git checkout -qb $BRANCHNAME
echo $RANDOM >> random1.txt
git add .
git commit -qam "$(date -Ins)"
git push -q $REMOTENAME $BRANCHNAME
pushd $BASEDIR/clone2 >/dev/null
git pull -q $REMOTENAME
git checkout -q $BRANCHNAME
echo $RANDOM >> random2.txt
git add .
git commit -qam "$(date -Ins)"
git push -q $REMOTENAME $BRANCHNAME
echo
echo 'git log --all --oneline --decorate --graph :'
git log --all --oneline --decorate --graph
echo
pushd >/dev/null
git checkout -q $BRANCHNAME
echo $RANDOM >> random1.txt
git commit -qam "$(date -Ins)"
echo 'git log --all --oneline --decorate --graph :'
git log --all --oneline --decorate --graph
echo
git fetch -q $REMOTENAME $BRANCHNAME
git merge -m "$(date -Ins)" $REMOTENAME/$BRANCHNAME
echo
echo 'git log --all --oneline --decorate --graph :'
git log --all --oneline --decorate --graph
git pull -q --no-edit $REMOTENAME $BRANCHNAME
echo
echo 'git log --all --oneline --decorate --graph :'
git log --all --oneline --decorate --graph
如果您运行它,输出将类似于以下内容:
warning: You appear to have cloned an empty repository.
warning: You appear to have cloned an empty repository.
git log --all --oneline --decorate --graph :
* 2326793 (HEAD, remrepo/master, master) 2013-03-19T10:56:42,838038000-0400
* 34ea848 2013-03-19T10:56:42,360743000-0400
git log --all --oneline --decorate --graph :
* 81cb43f (HEAD, master) 2013-03-19T10:56:43,057198000-0400
* 34ea848 (remrepo/master) 2013-03-19T10:56:42,360743000-0400
Already up-to-date.
git log --all --oneline --decorate --graph :
* 81cb43f (HEAD, master) 2013-03-19T10:56:43,057198000-0400
* 34ea848 (remrepo/master) 2013-03-19T10:56:42,360743000-0400
git log --all --oneline --decorate --graph :
* e60b993 (HEAD, master) Merge branch 'master' of /tmp/gittest/remrepo
|\
| * 2326793 2013-03-19T10:56:42,838038000-0400
* | 81cb43f 2013-03-19T10:56:43,057198000-0400
|/
* 34ea848 (remrepo/master) 2013-03-19T10:56:42,360743000-0400
从上面的输出中可以看出:
- 最后的fetch + merge序列对
git log...
的输出没有影响。 git merge
命令的输出是Already up-to-date.
,即使这不是事实(远程和本地版本库各自分别有一个提交)。- 在这个“合并”之后,本地分支(
master
)比跟踪分支(remrepo/master
)多了一个提交。 - 与fetch + merge序列相比,pull做了正确的事情(即更新跟踪分支并执行合并),尽管两组命令收到了完全相同的信息。
GIT_TRACE=2 git pull
命令,并查看调试输出。 - twalberg