将git回购全部重置回克隆状态?

将git回购全部重置回克隆状态?,git,clone,Git,Clone,我有一个有回购协议的盒子,我们称之为上游。我还有一个盒子很久以前克隆了它,我们称之为本地的 本地可能发生了很多事情,它可能有分支、标记等。我想将本地重置为与现代的git克隆一样的状态。我不想丢失工作目录中的更改,我希望所有的状态都是一样的 这个问题是有原因的(通常是使用克隆到temp,nuking.git并移动到它上面),但我想知道是否有其他方法可以用git来解决这个问题。我希望不必重新下载我不需要的内容。您可以使用此命令查看第一次提交及其哈希: git log --pretty=oneline

我有一个有回购协议的盒子,我们称之为上游。我还有一个盒子很久以前克隆了它,我们称之为本地的

本地可能发生了很多事情,它可能有分支、标记等。我想将本地重置为与现代的
git克隆一样的状态。我不想丢失工作目录中的更改,我希望所有的状态都是一样的


这个问题是有原因的(通常是使用克隆到temp,nuking.git并移动到它上面),但我想知道是否有其他方法可以用git来解决这个问题。我希望不必重新下载我不需要的内容。

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

git log --pretty=oneline | tail -1
然后运行此命令重置为该散列:

git reset --hard [commit hash]

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

然后,如果需要,重命名一个上游/原点远程,删除所有其他。例如,假设您打算使用
origin
的默认
git clone
远程名称,但现有存储库使用
upstream1
进行此操作,并具有第二个远程
upstream2
。删除
upstream2
(使用
git remote Remove
)并将
upstream1
重命名为
origin
(使用
git remote rename

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

下一步假定为非单分支。当您使用分支
X
的单个分支克隆时,我不确定
origin/HEAD
是什么,而origin的
HEAD
设置为
master
。如果你不担心单分支的不稳定性(或者你从来没有使用过
origin/HEAD
),这一切都不重要,但我在这里尝试完整

现在在剩下的遥控器上运行
git remote set head--auto
,例如,
git remote--set head origin--auto
。上一步和这一步之间有一个小的竞争。如果您将拥有
Git clone
d的上游Git一直在分支之间移动头部,这是不可避免的:您从他们那里获得的
HEAD
取决于您何时进行
Git clone
。但是,这将暴露运行
git clone
和运行此命令序列之间的差异。如果上游Git没有移动它的头,这里就没有竞争:它们的
Git fetch
Git remote set头
之间是稳定的

现在选择一个您想要的本地分支名称。通常,在具有所有默认值的全新
git克隆
中,您将拥有的一个本地分支是他们推荐的带有
头部
的分支,由于
git远程设置头部
,它现在被复制到您的
源/头部
。所以把它读出来(
git branch-r origin
,或者
git symbolic ref-refs/remotes/origin/HEAD
)看看是哪个分支。(可能是
master
)检查分支名称即使您的Git必须创建分支名称,也应该成功,并确保其上游设置为适当的远程跟踪名称(例如,
origin/master
),必要时进行更改。使用
git reset--hard@{upstream}
可以:

  • 移动它,如果git checkout没有创建它
  • 重置索引和工作树
然后删除其他目录和文件,并使用
git clean-dfx
删除所有未从初始
git签出中提取的目录和文件,
git clone
将作为其最后一步运行

现在您已经完成了,除非您想要一个浅层克隆,在这种情况下,您现在可能需要对当前存储库进行浅层化。您可以选择运行
git gc--prune=all
来清理包文件

小结,减去所有的摆弄单枝和浅枝等等 如果我们能做出一些合理的假设,过程就会简单得多。这些假设是:

  • 没有单一分支,没有分支浅,只有一个已正确设置的远程
    原点
  • 没有名为
    origin/*
    的本地分支机构在下面绊倒您
  • 没有其他需要清理的异常本地设置(例如,您没有在此存储库中
    git config user.name
    );及
  • 不想对git remote机顶盒大惊小怪(您可以随时这么做)
在本例中,过程是这样的,几乎可以剪切和粘贴,只需将
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
步骤通常是不必要的(这将是一个no op),但为了完整性,我将其包括在内

请注意,
git clean-dfx
步骤可能会删除许多可能有用的文件。
您说过,如果运行
git clone
,您需要的状态是,而这些可能有用的文件都不会被复制