是否可以控制git仓库状态的版本?

时间:2019-01-25 01:07:27

标签: git

我正在制作一个交互式git教程,用户可以通过遵循一系列说明并操作真实的git存储库来学习如何使用git。 为了防止学习者破坏存储库或采取错误的步骤(并导致本教程无法继续进行),我考虑每隔几步就对存储库状态(引用,索引和HEAD等)进行快照,然后重置发生意外情况时,转到最后一个。

对我来说,拍摄回购快照就像对.git文件夹进行某种版本控制一样,我想知道是否可以使用任何版本控制工具来完成工作吗?

我试图将一个git repo放入另一个git repo和该孩子的set the .gitignore of the parent repo to include .git文件夹中,但是没有运气。 git status不会将.git显示为未跟踪目录。

很高兴听到任何可以帮助我拍摄.git文件夹快照的技巧,或一些技巧来保存git repo的状态并稍后再应用。

编辑1

尝试git add -f强制添加.git文件夹,但是git拒绝添加该文件夹并抛出错误消息。

幸运的是,另一个真正愚蠢的把戏起作用了。将.git重命名为任何其他名称足以诱骗git将其视为普通文件夹。对于我来说,这是一个可以接受的解决方案,但不是完美的。

话虽这么说,由于@ErikMD提到我通过复制.git来保存git仓库状态的尝试乍看起来似乎不可行,我想知道我是否忽略了一些关键的事情?通过使用版本控制费用管理.git来保留git存储库的快照是否有问题?

1 个答案:

答案 0 :(得分:0)

乍看之下,您的“变通方法”似乎不可行(如果您尝试提交父git repo中包含的.git子文件夹,您将获得某种(损坏的)git-submodule ...)

更准确地说: Git并非旨在将.git文件夹的低级内容作为常规文件进行跟踪。取而代之的是,Git允许在根存储库中合并几个存储库(几个子文件夹,其中每个子文件夹包含一个.git子文件夹)。这对应于所谓的git submodule功能。但是正确设置子模块需要使用专用命令,这些命令又会更新特殊文件.gitmodules。因此,我之前说过,如果您不遵循正常的工作流程,则可能会获得“破碎的git-submodule布局”。实际上,与git subtree之类的最新功能相比,实践中git-submodules的使用相当繁琐。

但是,我认为您可以依靠git reflog或相关命令来恢复=覆盖历史记录,索引和工作目录(即,自动完成教程系统的存储库)存储库的3个主要部分)以及分支和标签…

为了说明我的建议,假设我们只处理一个分支:

  1. 当前活动分支(HEAD)的“状态”可以由相应的SHA1标识:

    $ git rev-parse --verify HEAD
    0ed45a5994bceea7c6b1d6530c72cd9ce29a46af  # for example
    
  2. 假设用户执行了错误的步骤:

    $ git add UnwantedFile && git commit -m "Unwanted commit"
      # or
    $ git reset --hard HEAD~3  # remove 3 commits by mistake
    

    (您会使用适当的命令注意到它)

  3. 然后,您可以恢复工作目录的状态。 +索引+当前分支,方法是:

    $ git reset --hard 0ed45a5994bceea7c6b1d6530c72cd9ce29a46af
    

    (或者,如果最初没有执行步骤1来记住先前的状态,则reflog可以给出所需的提示):

    $ git reflog
    d62277c84 HEAD@{0}: reset: moving to HEAD~3
    0ed45a599 HEAD@{1}: checkout: moving from master to V8.8.2
    …
    $ git reset --hard HEAD@{1}
    

最后,我只看到三种实现您想要的方法:

  1. 如果要回滚存储库,请使用手动rsyncbash hacks覆盖存储库,但这可能并不令人满意;
  2. 使用标准命令,例如git resetgit branchgit checkoutgit tag…(取决于您正在研究的教程的重点)来相应地重置存储库;
  3. 还是通过适当的命令(例如git push --mirrorgit pull / git fetch使用本地遥控器(或本地克隆,以一种方式或另一种方式)?