【问题标题】:How to get git repository pristine如何获得原始的 git 存储库
【发布时间】:2019-11-03 11:37:52
【问题描述】:

使用带有 git 存储库和已签出分支的构建机器。过了一段时间,事情发生了变化,历史被改写,东西被压扁,精心挑选并合并到开发机器上的其他地方并推送到远程。

然后开发人员回到构建机器并点击构建脚本,该脚本会清理、重置、获取,然后尝试拉出一些分支并构建它。不幸的是,这与已经在这台机器上构建的分支相同。而且由于事情发生了变化,它不能被快进并进入合并阶段。但是开发人员并不关心合并;如果可以的话,他们只会删除 repo 并再次克隆它,然后从远程签出分支。

但是,克隆 repo 和初始化所有子模块需要很长时间。那么,我们该如何帮助他们呢?克隆后如何让 git 存储库保持原始状态?

解决问题的可能脚本

git fetch
git clean -dfх
git submodule update --init --recursive
git reset --hard
git checkout -b $1 --track origin/$1 || echo ""
git pull  # <-- nope, would not work

理论上,-b $1 可以更改为一些-b someuniqueid,只检查“另一个”分支,它可能会起作用。但这并不理想。想法?

【问题讨论】:

  • 请edit 提出明确、具体的问题。
  • 你要求我们送货
  • 什么是原始状态?
  • 我认为它和完美无瑕一样:) 我会更新问题
  • 对不起。使用同义词无助于解释。您有未提交的更改吗?是没有变化的原始状态吗?

标签: git


【解决方案1】:
  1. 如果您使用子模块并且有人用git push -f 重写了您的子项目提交(可以使用git submodule status 看到的提交),您将无法从中恢复。甚至rm -rf ... &amp;&amp; git clone ... 也无济于事。

感谢git submodule status: https://stackoverflow.com/a/54238999/12118546

  1. 之前的答案是没有删除 repo 及其子模块中的任何额外(未跟踪)的东西,我会这样做(假设 master 分支):
git fetch origin
git reset --hard origin/master
git clean -ffxd
git submodule update --init --recursive --force
git submodule foreach --recursive 'git clean -ffxd'

感谢前两步:https://stackoverflow.com/a/14787801/12118546

感谢子模块提示:https://www.vogella.com/tutorials/GitSubmodules/article.html

  1. 我不确定我是否没有遗漏任何边缘情况。清除内容并克隆包括子模块在内的新存储库是最好的方法......

【讨论】:

  • “有人强迫你的“子项目提交”是什么意思?
  • 顺便说一句,git submodule sync --recursive 可能是您序列的一个很好的补充。也许--force on update 也可以提供帮助
  • @kreuzerkrieg 子模块通常指向存储库的特定提交。如果有人做了git push -f 并在您用作子模块的存储库中重写了原始提交,则无法从中恢复,因为您的超级存储库指向原始存储库中不再存在的提交。在这种情况下很难说什么是正确的行动。叹息,人们不应该使用git push -f,那么您需要的唯一操作就是git reset --hard; git checkout whatever; git pull。我们已经实现了这样的持续交付,生产在每次运行时都按照这个顺序进行。
  • 嗯...我想我明白了你的意思,不是我曾经遇到过,但我确实遇到过当子模块指向一个提交的情况,该提交后来被压扁并重写了历史,所以,从技术上讲您的回购指向不存在的提交。而且我不熟悉这种情况的任何解决方案,除了将子模块本地重新指向新提交
  • 在上面的脚本中发现了一个新内容。看这里gist.github.com/nicktoumpelis/11214362 有时需要第二个'f'
【解决方案2】:
git reset --hard

这会将您的所有源文件完全返回到您所在分支的源文件。如果您想这样做,请小心谨慎,因为如果您确实有想要保留的更改,它们可能会被覆盖。

现在您还描述了“git pull”创建了一个新的烦人合并版本的情况。此时你可以做的是:

git pull 
# oops, a merge created, what a mess
git reset HEAD^    # maybe need more ^'s - see below
git reset --hard 
git pull

第一个 git reset 命令将“删除”最后一次提交 - 合并提交 - 而不更改您的任何文件,因此它们将继续包含大量废话。所以第二个命令将摆脱所有这些废话。然后你可以再次“get pull”以再次获取最新版本。

如果您的分支比 master 领先多个,您实际上可能需要在此 HEAD^ 上执行多个“^”。用“git status”告诉你比master提前了多少次修订。

无论如何,只需一个接一个地执行这些命令,尝试了解发生了什么,并针对具体情况使用正确的命令。很难给你一个具体的命令列表(而我上面给出的具体列表可能不是你所需要的)。

【讨论】:

  • 其实我觉得git reset --hard origin/yourbranch可以解决,后面不需要pull
猜你喜欢
  • 2014-03-02
  • 2012-01-14
  • 1970-01-01
  • 1970-01-01
  • 2016-07-30
  • 2010-10-11
  • 2013-03-20
  • 2022-01-23
  • 1970-01-01
相关资源
最近更新 更多