13.2 对等工作区
这两个工作区本质上没有区别,但是往往提交是在一个版本(A)中进行的,另外一个(B)作为备份。对于这种对等工作区模式,版本库的同步只有一种可行的操作模式,就是备份库(B)执行git pull命令从源版本库(A)中拉回新的提交实现版本库同步。为什么不能从版本库A向版本库B执行git push推送操作呢?看看下面的操作。
执行克隆命令,将版本库/path/to/my/workspace/demo克隆到/path/to/my/workspace/demo-backup。
$git clone/path/to/my/workspace/demo/path/to/my/workspace/demo-backup
Cloning into/path/to/my/workspace/demo-backup…
done.
进入demo版本库,生成一些测试提交(使用—allow-empty参数可以生成空提交)。
$cd/path/to/my/workspace/demo/
$git commit—allow-empty-m "sync test 1"
[master 790e72a]sync test 1
$git commit—allow-empty-m "sync test 2"
[master f86b7bf]sync test 2
能够在demo版本库向demo-backup版本库执行PUSH操作吗?执行一下git push看一看。
$git push/path/to/my/workspace/demo-backup
Counting objects:2,done.
Delta compression using up to 2 threads.
Compressing objects:100%(2/2),done.
Writing objects:100%(2/2),274 bytes,done.
Total 2(delta 1),reused 0(delta 0)
Unpacking objects:100%(2/2),done.
remote:error:refusing to update checked out branch:refs/heads/master
remote:error:By default,updating the current branch in a non-bare repository
remote:error:is denied,because it will make the index and work tree inconsistent
remote:error:with what you pushed,and will require 'git reset—hard' to match
remote:error:the work tree to HEAD.
remote:error:
remote:error:You can set 'receive.denyCurrentBranch' configuration variable to
remote:error:'ignore' or 'warn' in the remote repository to allow pushing into
remote:error:its current branch;however,this is not recommended unless you
remote:error;arranged to update its work tree to match what you pushed in some
remote:error:other way.
remote:error:
remote:error:To squelch this message and still keep the default behaviour,set
remote:error:'receive.denyCurrentBranch' configuration variable to 'refuse'.
To/path/to/my/workspace/demo-backup
![remote rejected]master->master(branch is currently checked out)
error:failed to push some refs to '/path/to/my/workspace/demo-backup'
翻译成中文:
$git push/path/to/my/workspace/demo-backup
…
对方说:错了:
拒绝更新已检出的分支refs/heads/master。
默认更新非裸版本库的当前分支是不被允许的,因为这将会导致
暂存区和工作区与你推送至版本库的新提交不一致。这太古怪了。
如果您一意孤行,也不是不允许,但是你需要为我设置如下参数:
receive.denyCurrentBranch=ignore|warn
到/path/to/my/workspace/demo-backup
![对方拒绝]master->master(分支当前已检出)
错误:部分引用的推送失败了,至'/path/to/my/workspace/demo-backup'
从错误输出中可以看出,虽然可以改变Git的默认行为,允许向工作区推送已经检出的分支,但是这么做实在不高明。
为了实现同步,需要进入到备份版本库中,执行git pull命令。
$git pull
From/path/to/my/workspace/demo
6e6753a..f86b7bf master->origin/master
Updating 6e6753a..f86b7bf
Fast-forward
在demo-backup版本库中查看提交日志,可以看到在demo版本库中的新提交已经被拉回到demo-backup版本库中。
$git log—oneline-2
f86b7bf sync test 2
790e72a sync test 1
为什么执行git pull命令没有像执行git push命令那样提供那么多的参数呢?这是因为在执行git clone操作后,克隆出来的demo-backup版本库中对源版本库(上游版本库)进行了注册,所以在demo-backup版本库中执行拉回操作,无须设置上游版本库的地址。
在demo-backup版本库中可以使用下面的命令查看对上游版本库的注册信息:
$cd/path/to/my/workspace/demo-backup
$git remote-v
origin/path/to/my/workspace/demo(fetch)
origin/path/to/my/workspace/demo(push)
实际上,注册上游远程版本库的奥秘都在Git的配置文件中(略去无关的行):
$cat/path/to/my/workspace/demo-backup/.git/config
…
[remote "origin"]
fetch=+refs/heads/:refs/remotes/origin/
url=/path/to/my/workspace/demo
[branch "master"]
remote=origin