13.2 对等工作区

13.2 对等工作区 - 图1

这两个工作区本质上没有区别,但是往往提交是在一个版本(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


13.2 对等工作区 - 图2