本节学习如何使用git clone命令建立版本库克隆,以及如何使用git push和gitpull命令实现克隆之间的同步。

 Git的版本库目录和工作区在一起,因此存在一损俱损的问题,即如果删除一个项目的工作区,同时也会把这个项目的版本库删除掉。一个项目仅在一个工作区中维护太危险,如果有两个工作区就会好很多。

  

 图片中一个项目使用了两个版本库进行维护,两个版本库之间通过pull和push操作实现同步:

<1>版本库A通过克隆操作创建克隆版本库B

<2>版本库A可以通过push(推送)操作,将新提交传递给版本库B

<3>版本库A可以通过pull(拉回)操作,将版本库B中的新提交拉回到自身

<4>版本库B可以通过pull操作,将版本库A中的新提交拉回到自身

<5>版本库B可以通过push操作,将新提交传递给版本库A

 Git使用git clone命令实现版本库克隆,主要有三种用法:

<1>git clone <repository> <directory>

<2>git clone --bare <repository> <director.git>

<3>git clone --mirror <repository> <director.git>

这三种用法的区别:

<1>用法一将<repository>指向的版本库创建一个克隆到<directory>目录。目录<directory>相当于克隆版本库的工作区,文件都会检出,版本库位于工作区下的.git目录中。

<2>用法二和用法三创建的版本库都不包含工作区,直接就是版本库的内容,这样的版本库称为裸版本库。一般约定俗成裸版本库的目录以.git为后缀。

<3>用法三区别于用法二之处在于用法三克隆出来的裸版本对上游版本库进行了注册,这样可以在裸版本库中使用git fetch命令和上游版本库进行持续同步。

 对等工作区,不使用--bare或--mirror创建出来的克隆包含工作区,这样就会产生两个包含工作区的版本库,这两个版本库是对等的。

 这两个工作区本质上没有区别,但是往往提交是在一个版本中进行的,另外一个作为备份。对于这种对等工作区模式,版本库的同步只有一种可行的操作模式,就是备份库执行git pull命令从源版本库中拉回新的提交实现版本库同步。为什么不能从版本库A向版本库B执行git push推送操作呢?看下面的操作。

<1>执行克隆命令

[root@git demo]# git clone /git/my/workspace/demo /git/my/workspace/demo-backup
Initialized empty Git repository in /git/my/workspace/demo-backup/.git/

<2>进入demo版本库,生成一些测试提交(使用--allow-empty参数可以生成空提交)

[root@git demo]# git commit --allow-empty -m "sync test 1"
[master 4f18802] sync test 1
[root@git demo]# git commit --allow-empty -m "sync test 2"
[master e8d59b4] sync test 2

<3>能够在demo版本库向demo-backup版本库执行push操作吗?

[root@git demo]# git push /git/my/workspace/demo-backup/
Counting objects: 2, done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 270 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 /git/my/workspace/demo-backup/
! [remote rejected] master -> master (branch is currently checked out)
error: failed to push some refs to '/git/my/workspace/demo-backup/'

<4>为了实现同步,需要进入到备份库中执行git pull操作

[root@git demo]# cd /git/my/workspace/demo-backup/
[root@git demo-backup]# git pull
From /git/my/workspace/demo
06e5df8..e8d59b4 master -> origin/master
Updating 06e5df8..e8d59b4
Fast-forward
[root@git demo-backup]# git log --oneline -2
e8d59b4 sync test 2
4f18802 sync test 1

 下面介绍下裸版本库,裸版本库不但可以通过克隆的方式创建,还可以通过git init命令以初始化的方式创建,之后的同步和上面的同步方式大同小异。

 命令git init是用于初始化一个版本库的,之前执行git init命令初始化的版本库是带工作区的,如何以裸版本库的方式初始化一个版本库呢?答案是使用--bare参数。

<1>创建一个裸版本仓库。

[root@git repos]# git init --bare demo-init.git
Initialized empty Git repository in /path/to/repos/demo-init.git/

<2>查看一下demo-init.git下的内容

[root@git repos]# ls -F demo-init.git/
branches/ config description HEAD hooks/ info/ objects/ refs/

<3>查看一下这个版本库的配置core.bare的值

[root@git repos]# git --git-dir=/path/to/repos/demo-init.git config core.bare
true

<4>向裸版本库中推送数据,进入源版本库中执行操作

[root@git demo]# git push /path/to/repos/demo-init.git master:master
Counting objects: 21, done.
Compressing objects: 100% (13/13), done.
Writing objects: 100% (21/21), 1.90 KiB, done.
Total 21 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (21/21), done.
To /path/to/repos/demo-init.git
* [new branch] master -> master

<5>查看一下demo-init.git版本库中的提交

[root@git demo]# git --git-dir=/path/to/repos/demo-init.git log --oneline -2
e8d59b4 sync test 2
4f18802 sync test 1

<6>继续在demo中执行几次提交,再向demo-init.git中推送

[root@git demo]# git commit --allow-empty -m "sync test 5"
[master 2007420] sync test 5
[root@git demo]# git commit --allow-empty -m "sync test 6"
[master 49f01b9] sync test 6

[root@git demo]# git push /path/to/repos/demo-init.git
Counting objects: 2, done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 269 bytes, done.
Total 2 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (2/2), done.
To /path/to/repos/demo-init.git
e8d59b4..49f01b9 master -> master

 为什么这次使用git push命令后面没有跟上分支名呢?这是因为远程版本库中已经不再是空版本库了,有名为master的分支,通过以下命令查看远程版本库分支

[root@git demo]# git ls-remote /path/to/repos/demo-init.git
49f01b9d4d7a4c558def93fcbe88f8e3137b5b6f HEAD
49f01b9d4d7a4c558def93fcbe88f8e3137b5b6f refs/heads/master

最新文章

  1. 移动端城市选择JavaScript插件(基于WG的城市选择插件的修改版本)
  2. filter,map,reduce,lambda(python3)
  3. Android Hook Dexposed原理小析
  4. object-c面向对象1
  5. MySQL操作备忘录
  6. 开启mysql慢查询日志并使用mysqldumpslow命令查看
  7. MySQL数据库的环境及简单操作
  8. 在PHP中,将一个汉字数组按照拼音首字母进行排序
  9. React——共享state
  10. C# 使用SmtpClient发送Email
  11. pymysql常见问题
  12. Python中re的match、search、findall、finditer区别
  13. deep learning RNN
  14. Linux centos6.7网卡配置
  15. rsync使用详解
  16. net abp core的appservice中访问httpcontext对象
  17. C# 在网页中将Base64编码的字符串显示成图片
  18. JeeSite 4.x 树形结构的表设计和用法
  19. i春秋CTF web题(1)
  20. Distribution(F题)---第八届河南省程序设计大赛

热门文章

  1. 命令:curl
  2. java基础知识—抽象和封装
  3. 小程序 onReachBottom 事件快速滑动时不触发的bug
  4. Python机器学习(基础篇---监督学习(k近邻))
  5. nginx配置支持http2
  6. 马凯军201771010116《面向对象与程序设计Java》第十三周学习总结
  7. python判断两个变量是否为同一数据类型
  8. 高性能JavaScript(1)
  9. Vue组件中的问题
  10. wxPython制作跑monkey工具(python3)-带事件百分比显示界面