将git repo完全重置回克隆状态?

时间:2019-03-29 13:53:38

标签: git clone

我有一个带有仓库的盒子,我们称其为上游。我还有一个很久以前就克隆了它的盒子,我们称它为本地。

很多事情可能发生在本地,它可能有分支,标签等。我想将本地重置为与现代git clone相同的状态。我不想只是丢失工作目录中的更改,我希望所有状态都相同。

这个问题有other solutions(通常使用克隆到临时文件,对.git进行移动并将其移到上面),但是我想知道是否还有另一种方法可以仅通过git来完成。我希望不必重新下载不需要的内容。

2 个答案:

答案 0 :(得分:1)

首先,撤消任何单分支或浅度的操作,除非新克隆将是单分支和/或浅的(在这种情况下,任何单分支或浅度的操作,但在过程结束时进行浅化处理)。清除.git/config中累积的所有其他非标准设置,而不是您在git clone操作中手动设置的设置。

然后,如果需要,重命名一个上游/原始远程,删除所有其他。例如,假设您打算使用默认的git clone远程名称origin,但是现有存储库为此使用upstream1并拥有另一个远程upstream2。删除upstream2(带有git remote remove),并将upstream1重命名为origin(带有git remote rename)。

然后,使用git fetch--prune选项对保留的远程名称运行--prune-tags。默认值为origin,因此,如果您保留默认值,则只需git fetch -p,因为这意味着git fetch =p origin。 (我不确定100%地确定 current 分支的上游设置会发生什么,无论它是什么,如果它是其他远程对象,那么您可能只想运行git fetch -p origin在所有情况下都是安全的。)

此下一步假定非单分支。我不确定origin/HEAD是什么,当您使用原始分支X设置为HEAD的分支master的单分支克隆时。如果您不担心单分支的情况(或者您从未使用过origin/HEAD),那么这都不重要,但是我想在这里完成。

现在在其余的远程服务器上运行git remote set-head --auto,例如git remote --set-head origin --auto。上一步和此步骤之间存在轻微的竞争。如果您本来git clone d的上游Git始终将其HEAD从一个分支移动到另一个分支,那是不可避免的:您从它们那里获得的HEAD取决于何时< / em>您做了git clone。但是,这将揭示运行git clone与运行此命令序列之间的区别。如果上游的Git 移动其HEAD,那么这里就没有种族:他们的HEADgit fetchgit remote set-head之间是稳定的。

现在选择您想要的一个本地分支名称。通常,在具有所有默认设置的全新git clone中,您将拥有的一个本地分支是他们推荐的HEAD分支,由于{而将其复制到您的origin/HEAD {1}}。因此,请读出该内容(例如,git remote set-headgit branch -r origin)以查看是哪个分支。 (可能是git symbolic-ref refs/remotes/origin/HEAD。)签出那个分支名称-即使您的Git必须 create ,分支名称也应成功执行,并确保其上游设置为适当的远程跟踪名称(例如master),并在必要时进行更改。使用origin/master可以:

  • 如果没有git reset --hard @{upstream}创建它,请移动它;
  • 重置索引和工作树

,然后删除其他目录,并使用git checkout删除所有不会从git clean -dfx开始运行的初始git checkout中提取的所有目录和文件。

您现在已经完成了,除非您想要浅表克隆,在这种情况下,您现在可能需要浅化当前存储库。您可以选择运行git clone来清理打包文件。

总结,减去所有带有单分支和浅等的摆弄

如果我们可以做出一些合理的假设,则过程将变得更加简单。假设是:

  • 没有单分支机构,没有浅薄程度,只有一个已经正确设置的远程git gc --prune=all
  • 没有任何名为origin local 分支机构来绊倒您;
  • 没有其他需要修改的严格本地设置(例如,您没有origin/*在该存储库中);和
  • 不想大惊小怪git config user.name(不过您可以随时这样做)。

在这种情况下,过程就是这样,它几乎可以剪切和粘贴,只需将git remote set-head更改为要保留的分支:

master

(以上未经测试,请小心!)。 git fetch -p --prune-tags git checkout master # or whatever branch you intended to keep git branch --set-upstream-to=origin/master # use correct origin/ name here git reset --hard origin/master # update work-tree git clean -dfx # remove non-committed stuff from work-tree git for-each-ref --format='%(refname:short)' refs/heads | while read name; do [ "$name" == "master" ] && continue # skip the one to keep git branch -D "$name" # delete the others done 步骤通常是不必要的(这是一个空操作),但出于完整性考虑,我将其包括在内。

请注意,--set-upstream-to步骤可能会删除很多可能有用的文件。您说过,您想要运行git clean -dfx时的状态,并且所有可能有用的文件都不会被 git clone复制。从you are probably doing this to avoid this particular git clean type of effect开始,您可能要省略或至少修改git clone步骤。

答案 1 :(得分:0)

您可以使用此命令查看您的第一次提交及其哈希值:

git log --pretty=oneline | tail -1

然后运行此命令以重置为该哈希值:

git reset --hard [commit hash]