如何设置本地Git仓库和本地备份目录?

4

更新

我按照以下答案中的指示设置了两个Git存储库,但是备份目录中没有工作目录中文件的副本。这是我在备份目录中看到的内容...

$ ls
total 0
drwxr-xr-x  10 Hristo  staff  340 Feb 25 21:40 Kamma.git

…但我希望看到以下类似的内容...

$ ls
total 16
drwxr-xr-x   6 Hristo  staff   204 Dec 19 19:51 css
drwxr-xr-x   3 Hristo  staff   102 Nov 13 18:00 images
-rw-r--r--@  1 Hristo  staff  4440 Feb 26 03:20 index.html
drwxr-xr-x  15 Hristo  staff   510 Feb 24 14:19 js

我希望我的主工作目录是 /Users/Hristo/Sites/Kamma,在这里我可以进行更改、提交、还原等操作。

我想要一个备份目录 /Users/Hristo/Sites/Kamma_bak,用来定期推送重要更改,例如项目的新版本,其中所有文件都是工作目录的副本,只不过不是最新的副本。

希望这样说得清楚明白。


原始帖子

我想设置一个本地Git仓库。例如,我的主目录是 /Users/Hristo/Sites/Kamma,我会在这里完成所有工作。

我希望能够像Subversion一样提交更改和还原以前的版本等操作。但我也希望有一个备份目录 /Users/Hristo/Sites/Kamma_bak,作为一种故障保护,在这里我会偶尔“推送”版本。

在这个备份目录 /Users/Hristo/Sites/Kamma_bak 中,我希望所有文件等都存在于工作目录 /Users/Hristo/Sites/Kamma 的副本中,作为备份副本。

我应该如何使用Git来实现这一点呢?我已经在我的机器上安装了它,运行的是Snow Leopard。

3个回答

5

是的,你完全可以这样做。不过我建议你的备份文件夹在另一台计算机上。

请阅读这个帖子:如何有效地同时使用Git和Dropbox?

我认为这些说明正好提供了你要找的内容;“dropbox”部分当然是可选的(它只是一个文件夹)。

编辑:忘记Dropbox吧。Dropbox只是一个本地文件夹+一个将其复制到离线位置的服务。这些说明也适用于你自己的本地文件夹。

重要的是要创建一个(本地的)裸仓库,将其设置为“git remote”,并将更改推送到其中。

让我从引用的帖子中复制粘贴,并为您进行修改。

类似这样的东西应该可以工作:

~/Sites/Kamma $ git init
~/Sites/Kamma $ git add .
~/Sites/Kamma $ git commit -m "first commit"
~/Sites/Kamma $ cd ~/Sites/Kamma_bak

~/Sites/Kamma_bak $ mkdir Kamma.git
~/Sites/Kamma_bak $ cd Kamma.git
~/Sites/Kamma_bak $ git init --bare
~/Sites/Kamma_bak $ cd ~/Sites/Kamma

~/Sites/Kamma $ git remote add origin ~/Sites/Kamma_bak/Kamma.git
~/Sites/Kamma $ git push origin master

gitHub 是一个不错的离线选项。 - Devin Ceartas
@Devin... 我知道GitHub,但我不想在远程服务器上托管,也不想让我的工作立即公开。 @Rich... 我并不是在寻找Dropbox解决方案。我希望所有东西都在本地。 - Hristo
@Hristo,你没有读懂我的话。忘记Dropbox吧。Dropbox只是一个本地文件夹+一个将其复制到离线位置的服务。这些指令对你也适用。重要的是创建一个空的repo,将其设置为远程repo并将更改推送到该repo。 - Rich
@Rich...看起来好像成功了。谢谢!不过,这可能是因为我不知道Git如何工作,但Kamma目录中的文件都没有出现在Kamma_bak目录中。我希望Kamma_bak目录像一个备份一样...我以为所有的文件也会出现在那里? - Hristo
@Hristo。Kamma_bak目录包含一个名为.git的文件夹 - 其中包含所有文件及其历史记录。是的,你最好多了解一下git :-) - Rich
备份目录仅显示Kamma.git。推送的文件未出现在Kamma_bak文件夹中。有解决方案吗?有人能告诉我哪里出错了吗? - Mohith7548

1
注意:在同一台机器上的“备份”副本并不是真正的备份(特别是如果它在同一硬盘上)。为了可靠,您确实需要将数据复制到一个(或多个!)不同的机器/媒体上,最好在不同的位置。
听起来你的“备份”是一个裸仓库,但你希望它成为非裸仓库(即你希望它有自己的工作树被检出)。
问题在于向非裸仓库推送通常不是一个好主意。实际上,这样的推送很可能会更新HEAD指向的分支,而不更新索引或工作树。这可能会导致接收仓库中非常混乱的情况(例如,添加的文件显示为已删除状态等)。因此,Git版本1.7.0及更高版本默认拒绝接受对非裸仓库当前检出的分支的推送。
注意:当您将代码推送到裸仓库进行备份时,所有提交的文件都在那里,只是没有被检出(它们被压缩并保存在 Git 对象存储中作为“松散对象”和“包文件”)。推送的数据表示您提交和推送的内容的完整历史记录的副本。您无法直接访问内容。相反,您必须将其克隆到非裸仓库(因此检出提交)或使用git archive提取一组文件,而无需额外的仓库或完整的检出。

我并不确定你需要描述的东西。

如果您需要检查存储库的旧快照(并且您不想在正常工作存储库中执行此操作),那么您只需要克隆一个临时副本并检出所需的旧提交。本地克隆非常便宜,因为它们可以将对象存储文件硬链接而不是复制它们。历史提交图通常是您“回到过去”所需的全部内容。虽然Git会让您随意重写历史记录图,但您实际上并没有使不可恢复的更改的危险,因为它通常需要-f/--force开关和/或提供恢复机制(reflogs、refs/original/、收集未引用对象之前的最小年龄要求等)。

在编程中,拥有另一个存储库(尤其是在另一台机器的另一个位置)以备份提交记录是个好主意,这样你就可以从(例如)rm -rf working_repo中恢复,但通常裸仓库已经足够了。当你需要恢复时,只需克隆即可。当你想要检查一些旧的快照而不干扰你的正常工作存储库时,可以在其他地方创建临时克隆。通过良好的提交习惯,git diffgit log(特别是-p-S选项)和git show通常可以提供你想要的任何“考古学”信息,而无需检出任何内容(它们甚至可以在裸仓库中使用)。


然而,如果你愿意承担风险,你可以做你想做的事情。

像任何其他“锋利”的工具一样,Git也会让你冒着“自己给自己脚打针”的风险(请原谅这个混合比喻)。

  1. 创建并配置备份存储库,并将其添加为工作存储库中的远程存储库。

    # 存储库路径
    WORKING=/path/to/working
    BACKUP=/path/to/backup
    
    # 工作存储库中备份存储库的名称
    REMOTE=backup
    
    ! test -d "$BACKUP" || (echo "error: $BACKUP already exists"; exit 1) &&
    git clone --origin working "$WORKING" "$BACKUP" &&
    ( cd "$BACKUP" &&
      git config receive.denyCurrentBranch false &&
      git remote rm working
    ) &&
    ( cd "$WORKING" &&
      git remote add "$REMOTE" "$BACKUP" &&
      git config remote."$REMOTE".push 'refs/heads/*:refs/heads/*'
    )
    
  2. 在备份存储库中设置一个 post-receivepost-update 钩子,执行 git reset --hard。这将使索引和工作树与当前检出的分支保持同步。

    Git FAQ “Why won't I see changes in the remote repo after "git push"?” 指向一个示例 post-update 脚本,可以相对安全地执行此操作(如果工作树或索引处于脏状态,则会保存一个存储区——如果推送了具有相同路径名的新添加文件,则仍可能会丢失未跟踪的文件)。

    ( H="$BACKUP"/.git/hooks/post-update &&
      curl http://utsl.gen.nz/git/post-update >$H && chmod +x "$H" )
    
  3. 在需要更新备份存储库时将其推送到远程存储库。

    (cd "$WORKING" && git push "$REMOTE")
    
如果你使用这样的设置,你应该绝对避免在备份工作树中工作。你在那里进行的任何提交、留下的任何已暂存更改以及留下的任何未跟踪文件都可能会丢失。

1

git init 会创建一个 git 仓库。为了备份,可以在原始仓库上执行 git clone --no-hardlinks 命令进行复制。然后就可以从一个仓库推送到另一个仓库。


这就是我尝试的...但我收到了一条消息:致命错误:没有配置目标推送。 - Hristo
除非您已经为推送配置了目标,否则您需要手动指定它。 - Ignacio Vazquez-Abrams
与克隆指定方式相同。 - Ignacio Vazquez-Abrams
我的意思是,我该如何配置它,以便每次推送时都不必指定它? - Hristo
在配置中设置 branch.<name>.remote。有关更多详细信息,请参阅 git-config(1) 手册页。 - Ignacio Vazquez-Abrams

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接