我有一个带有仓库的盒子,我们称其为上游。我还有一个很久以前就克隆了它的盒子,我们称它为本地。
很多事情可能发生在本地,它可能有分支,标签等。我想将本地重置为与现代git clone
相同的状态。我不想只是丢失工作目录中的更改,我希望所有状态都相同。
这个问题有other solutions(通常使用克隆到临时文件,对.git进行移动并将其移到上面),但是我想知道是否还有另一种方法可以仅通过git来完成。我希望不必重新下载不需要的内容。
答案 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,那么这里就没有种族:他们的HEAD
在git fetch
和git remote set-head
之间是稳定的。>
git clone
中,您将拥有的一个本地分支是他们推荐的HEAD
分支,由于{而将其复制到您的origin/HEAD
{1}}。因此,请读出该内容(例如,git remote set-head
或git 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]