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

