Git:将未提交的更改备份到远程代码库

7
我希望备份本地未提交的更改到远程代码库以进行备份(以防本地硬盘损坏等)。在TFSC中,我会将更改“搁置”到一个存储于TF服务器上的 shelveset 中。
我的尝试:
- 我创建了一个名为 "backup_2021-02-13" 的新分支并切换到它。 - 我提交了更改。 - 我将其推送到远程仓库。
此时,我的更改已保存在远程代码库中(这意味着如果本地硬盘损坏,我可以恢复信息)。
但现在我有以下问题:
无论是在“master”分支还是在“backup_2021-02-13”分支,我都看不到之前挂起的更改:在备份分支上看不到它们,因为它们已经被提交(是的,更改存在,但已经提交)。在主分支上看不到它们,因为那里根本不存在这些更改。
但我想继续工作,就像备份过程从未发生过一样(所有未提交的更改仍然未提交)。
所以,我所做的是将备份分支中的更改合并到主分支中(无提交,ff-only,squash)。这样,我在主分支中有了未提交的更改,就像在任何备份工作之前一样。
但我怀疑这不是正常的做法。
那么,备份本地未提交的更改到远程代码库的正确(和最简单)方法是什么?同时保持当前(主)分支不变(所有未提交的更改仍然未提交)?
3个回答

7

你的过程没问题。在切换到 master 分支后,你只需要恢复备份分支中已提交的更改即可:

git checkout master
git checkout backup_2021-02-13 -- .

第二个命令会从分支backup_2021-02-13恢复所有文件。继续工作。

谢谢你的回答!它有效! :-) 但是,我不太理解为什么/如何。在文档 https://git-scm.com/docs/git-checkout 中,我甚至不知道你的解决方案使用了其中的哪一个 git checkout 的7个替代方案之一。 (看来,我对 Git 不够聪明... :-| ) - eikuh
“git checkout” 命令在现代的 “git” 中有些混淆,因此被拆分为 “git switch”(用于分支)和 “git restore”(用于文件)。在命令 “git checkout master” 中,它切换分支(文档中的第一个替代方案),而 “git checkout backup_2021-02-13 -- .” 则将指定分支的所有文件恢复到当前目录中(文档中的第七个替代方案);这里的单点表示当前目录。 - phd
难道不是第五个选择吗? 在我的文档中,第五个是: git checkout [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <pathspec>…​ 而第七个是: git checkout (-p|--patch) [<tree-ish>] [--] [<pathspec>…​] - eikuh
@eikuh 是的,5和6 - phd

2

@phd的答案是正确的,也许是您需要的正确答案。只需考虑它是部分备份,仅包括您的工作目录。我的意思是,这样做会丢失索引的更改。相反,如果要存储索引的更改,您需要创建另一个提交。因此,从主分支开始:

git checkout -b my_backup
git commit -m "first the index"
git add .
git commit -m "and now the working dir"
git checkout --detach HEAD
git reset HEAD~1
git reset --soft master
git checkout master

这段内容相对较长,但你可以将它转移到脚本中(或许带有备份分支名称和当前分支的参数),并且它也很容易理解。 git stash 做了类似的事情,但脚本会稍微复杂一些,而且我不确定 stash 的逻辑在未来是否会发生变化。目前,完整的 stash 会创建三个提交:一个包含索引的提交、一个包含未跟踪更改的提交,以及另一个是前两个提交和 HEAD 本身的合并提交。


谢谢你的回答!我必须承认,我不知道你所说的“你正在失去索引的更改”的确切含义。我在互联网上找到了两种“git index”的定义:(A)暂存区和(B)整个工作区的文件或目录索引。(可能,A和B有些相关,因此是相同的)。如果你指的是(A),那么我会失去哪些文件在暂存区的信息,那么我并不是很在意,因为这个信息对我来说不是很重要。如果你指的是(B),那么Git难道不能自动处理每个仓库的索引吗? - eikuh
把索引视为下一个要提交的所有内容。你应该关注它,因为用最少的努力保持自己的历史记录清晰是很重要的。你可能对工作目录做出了许多更改,但是你不希望将它们全部包含在单个提交中,所以你需要为每个提交移动一些更改到索引中,然后再进行提交。我建议你习惯于使用索引 :) - Marco Luzzara
1
这对我来说并没有太多意义。暂存区里面有什么,没有什么并不是非常重要的信息。如果我的硬盘崩溃了,那么我只需要查看所有未提交的文件,并再次决定下一步想提交什么。因此,我不认为有必要备份暂存区中的信息。 - eikuh
正如我所说,被接受的答案是适合你需求的正确答案。我只是添加了我的回答,因为为了完全备份git仓库,你还需要备份索引。此外,假设你已经进行了一些部分添加(git add -p),你不想再重复它们。 - Marco Luzzara
在我的工作流中,我会在提交之前不久将更改添加到暂存区,因此备份它没有太多意义。在提交之前长时间构建暂存区是一种常见的做法吗? - pabouk - Ukraine stay strong

1
你走在正确的道路上。为了将你的更改保存到远程仓库,你需要提交到非主分支并推送(例如备份_2021-02-13)。
大多数人所做的是在一个分支上进行开发,直到完全完成,然后像你所做的那样将更改合并到主分支(ff,压缩)。这个开发分支本质上是日常“搁置”的更改。
要查看你的分支中未决的更改,只需执行“git diff master”即可查看更改。

非常感谢您的回答!不过,我会接受phd的回答,因为这更符合我的常规工作流程,在主分支中保留待处理更改而不是在第二分支中(使用Visual Studio 2019查看待处理更改)。 - eikuh
我认为通常每个提交都应该包含一个可工作的代码 - 即使在开发分支中也是如此。这不是备份的情况。你不能总是在需要创建备份的时候完成一个可工作的代码。或者我有什么遗漏吗? - pabouk - Ukraine stay strong

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接