Git裸版本库

Table of Contents

1 Why

是为了作为备份的版本库或者共享式的版本库使用的。 不仅能节省存储空间(没有工作区和暂存区),而且便于使用git push向其推送更新。

2 What

创建一个裸版本库

$ git clone --bare ./git-exercise/ git-exercise-backup
Cloning into bare repository 'git-exercise-backup'...
done.

与原版本库作比较

$ diff ./git-exercise/.git/ ./git-exercise-backup/
Only in ./git-exercise/.git/: COMMIT_EDITMSG
diff ./git-exercise/.git/config ./git-exercise-backup/config
4,5c4
<       bare = false
<       logallrefupdates = true
---
>       bare = true
8a8,9
> [remote "origin"]
>       url = c:/Documents and Settings/lhou/./git-exercise/
Common subdirectories: ./git-exercise/.git/hooks and ./git-exercise-backup/hooks
Only in ./git-exercise/.git/: index
Common subdirectories: ./git-exercise/.git/info and ./git-exercise-backup/info
Only in ./git-exercise/.git/: logs
Common subdirectories: ./git-exercise/.git/objects and ./git-exercise-backup/objects
Only in ./git-exercise-backup/: packed-refs
Common subdirectories: ./git-exercise/.git/refs and ./git-exercise-backup/refs

这里,就可以看到,

  • 裸版本库中没有目录index,也即,没有暂存区
  • 裸版本库中没有目录logs,故git reflog不可用
  • 裸版本库中多了文件packed-refs
$ cat packed-refs
# pack-refs with: peeled
72c4cc512164e21f585535ac2976c20e665c28d2 refs/heads/master
$ git cat-file -p 72c4cc
tree 9986876438a022f2cca5ca26f166a0a0cf53861f
author tech-note <Email Addr> 1361946631 +0800
committer tech-note <Email Addr> 1361946631 +0800

start

尝试几个命令

$ cd ./git-exercise-backup/
$ ls -l
total 2
-rw-r--r--    1 lhou     Administ       23 Feb 27 16:33 HEAD
-rw-r--r--    1 lhou     Administ      203 Feb 27 16:33 config
-rw-r--r--    1 lhou     Administ       73 Feb 27 16:33 description
drwxr-xr-x    1 lhou     Administ        0 Feb 27 16:33 hooks
drwxr-xr-x    1 lhou     Administ        0 Feb 27 16:33 info
drwxr-xr-x    1 lhou     Administ        0 Feb 27 16:33 objects
-rw-r--r--    1 lhou     Administ       85 Feb 27 16:33 packed-refs
drwxr-xr-x    1 lhou     Administ        0 Feb 27 16:33 refs
$ git ls-files
$ git ls-tree HEAD
100644 blob d44e18fb93b7107b5cd1b95d601591d77869a1b6    1st.txt
$ git cat-file -p d44e18
start
$ git log
commit 72c4cc512164e21f585535ac2976c20e665c28d2
Author: tech-note <Email Addr>
Date:   Wed Feb 27 14:30:31 2013 +0800

    start
$ git checkout HEAD
fatal: This operation must be run in a work tree

3 How to use

先更新下原版本

$ cd ../git-exercise
$ cat 1st.txt
start
$ echo "hello" >> 1st.txt
$ git add .
$ git commit -m "hello"
686db8a] hello

尝试将更新推送到备份的裸版本库

$ git push
fatal: No configured push destination.
Either specify the URL from the command-line or configure a remote repository using

    git remote add <name> <url>

and then push using the remote name

    git push <name>

失败了!因为未设定远程版本库。 再次尝试

$ git push ../git-exercise-backup/
warning: push.default is unset; its implicit value is changing in
Git 2.0 from 'matching' to 'simple'. To squelch this message
and maintain the current behavior after the default changes, use:

  git config --global push.default matching

To squelch this message and adopt the new behavior now, use:

  git config --global push.default simple

See 'git help config' and search for 'push.default' for further information.
(the 'simple' mode was introduced in Git 1.7.11. Use the similar mode
'current' instead of 'simple' if you sometimes use older versions of Git)

Counting objects: 5, done.
Writing objects: 100% (3/3), 249 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To ../git-exercise-backup/
   72c4cc5..686db8a  master -> master

上面一大段提示,是在说,应该设置一个默认的推送(push)目的地,这样,就可以直接用git push了!这里到底成功了吗?

$ git log
commit 686db8a064b6a2cf1b1dc899a0cb1175d63871dd
Author: tech-note <Email Addr>
Date:   Wed Feb 27 17:41:15 2013 +0800

    hello

commit 72c4cc512164e21f585535ac2976c20e665c28d2
Author: tech-note <Email Addr>
Date:   Wed Feb 27 14:30:31 2013 +0800

    start
$ cd ../git-exercise-backup/
$ git log
commit 686db8a064b6a2cf1b1dc899a0cb1175d63871dd
Author: tech-note <Email Addr>
Date:   Wed Feb 27 17:41:15 2013 +0800

    hello

commit 72c4cc512164e21f585535ac2976c20e665c28d2
Author: tech-note <Email Addr>
Date:   Wed Feb 27 14:30:31 2013 +0800

    start

明显是成功了!因为裸版本库的日志更新了。 那么当我们上述原始版本丢掉后,怎么使用该裸版本库恢复出一个有工作区的、可正常使用的版本呢? 答案如下,

$ git clone git-exercise-backup/ from-git-exercise-backup/
Cloning into 'from-git-exercise-backup'...
done.
$ cd ./from-git-exercise-backup/
$ ls
1st.txt
$ cat 1st.txt
start
hello
$ git log
commit 686db8a064b6a2cf1b1dc899a0cb1175d63871dd
Author: tech-note <Email Addr>
Date:   Wed Feb 27 17:41:15 2013 +0800

    hello

commit 72c4cc512164e21f585535ac2976c20e665c28d2
Author: tech-note <Email Addr>
Date:   Wed Feb 27 14:30:31 2013 +0800

    start

Last Updated 2015-11-15 Sun 15:46.

Created by Howard Hou with Emacs 24.5.1 (Org mode 8.2.10)