这是我的问题。假设我有一个名为' app.js'的文件的回购。在主分支上。然后我创建一个新的分支并检查该分支。有没有办法在' app.js'上编辑和保存更改?在新分支中,然后切换回主服务器并拥有我可以在编辑器中打开的原始文件?如果我在文本编辑器中打开文件,它只是将它保存在我拥有它的文件夹中,无论我在哪个分支。很抱歉,如果这是一个菜鸟问题,感谢您的支持!
答案 0 :(得分:3)
Git,在内部,可以有任意数量的不同文件都命名为app.js
,并且可以通过commit-hash或其他提交说明符区分它们,例如HEAD
或分支名称:
git show HEAD:app.js
git show a9fc302:app.js
git show master:app.js
等等。您的编辑是否可以执行此操作,如果是这样,是否有关于您的编辑器的问题。
请注意,您的编辑器使用存储在计算机普通文件存储系统中的普通文件,位于工作树中,这是Git允许您完成工作的地方。使用Git时,您必须记住,Git主要关注的是提交,它们(主要)是permament,(完全)只读,每个文件的快照在文件具有的状态,当你提交它。但是Git提交的文件不一定来自工作树!
Git以特殊的压缩格式存储 Git的文件。提交文件后,只要提交本身存在,它们就是只读的,但由于它们采用特殊的Git格式,因此只有Git可以直接访问它们。当您检查某些提交(通过某个分支名称,例如git checkout
)时,git checkout branch
执行的操作是提取这些只读文件:
首先,Git将它们复制到Git的索引。索引也称为临时区域,有时也称为缓存。在索引中,文件仍然具有特殊的Git形式,但现在可以覆盖。
那么 - 实际上,在复制到索引的同时,因为它更有效--Git将每个文件的 index 版本提取到您的工作中 - 树,将特殊的Git-only表单解压缩为计算机系统其余部分可以使用的表单。
因此,您所处理的文件的 work-tree 副本实际上并不是Git的文件。当您运行git add file
时,您告诉Git将 file
的工作树版本复制到Git的索引中。此时,Git将文件压缩为特殊的仅Git格式,并使用新替换文件覆盖该文件的当前索引版本。
结果是索引始终包含,准备提交,将进入下一次提交的文件。它从当前提交的所有文件开始,采用特殊的Git形式,它与您的编辑理解的日常形式的工作树中的所有文件相匹配。但在那之后,您可以根据需要更改,修改工作树文件fold, spindle, or mutilate。这对索引中的版本没有影响,除非您运行git add
将工作树文件复制回索引,否则将覆盖索引版本。
这是未提交提交的更改与提交提交的更改之间的区别:正在运行git status
Git与当前提交进行比较到索引,并且暂存用于提交,因为您将其复制到索引中。然后,git status
让Git将索引与工作树进行比较: 没有为提交而暂停,因为你有尚未将其复制到索引中。
您的编辑器无法直接处理索引文件。 1 它必须适用于工作树文件。为了您自己的理智,以及易于使用大多数标准编辑器,在工作树区域内外以多个不同的名称保存某些文件的多个不同版本更有意义。
1 可能有一些可以,但如果是这样,他们可能通过将索引文件解压缩到常规文件来执行此操作,然后使用git add
将其重新放入指数。索引的内部格式可能会在每个新的Git版本中发生变化,因此过分依赖它是不明智的。
答案 1 :(得分:0)
你所描述的主要是git的默认行为,除了有几个陷阱。一些背景,然后是一些可能的解决方案:
<强>背景强>
主要是默认行为&#34;,我的意思是:分支的点(部分)你可以在文件版本之间来回切换,通过切换分支机构。
但这仅适用于与分支相关的更改;并且只有在commit
更改时才会发生该关联。当你只是编辑,保存和修改文件时,但没有提交它 - 那么你的更改存在于工作树中,也可能存在于索引中,但是git还没有将它们与分支相关联。
因此,当您运行git checkout
来切换分支时,git应该发出警告并拒绝结帐 - 在某些情况下,数据可能会丢失。但是,如果文件在最后一次提交到两个分支时是相同的,它将在切换分支时保持工作树和/或索引中的更改。 (在命令行中,它至少会给你一些反馈,告诉你这件事。
$ git checkout master
M file1
Switched to branch 'master'
表示未提交的更改已在file1
中结转。)
<强>解决方案强>
提交
您可能在评论中看到的第一个解决方案是提交更改。如果更改已准备好提交,这是一个很好的解决方案。即使他们还没有准备好参与永久提交,只要你不push
提交,你就可以随时将其编辑回历史记录 - 例如使用--amend
选项进行下一次提交。
藏匿
但也许您有一些阶段性的更改,以及其他未经暂停的更改,而您现在还不想将它们组合到一个提交中。或者也许出于其他原因,你不会觉得做出改变是正确的。
您可以做的另一件事是藏匿更改。这确实仍然会创建临时提交,但它会尝试将暂存和未暂存的更改分开,并提供对将其更改还原到其先前状态的支持。请参阅git stash
文档。
git checkout branch
# edit some stuff
git add .
# edit more stuff
git stash
# NOTE: at this point it will look like your changes have simply been
# reverted; but they haven't.
git checkout master
# now you have the `master` versions of all files
# ... do stuff ...
git checkout branch
git stash pop
# branch version of file is back
多个工作树
stash
并不坏,但并不总是完美。
也许您希望同时在多个分支上进行未提交的更改。这可以通过存储来完成,但是你必须保持正确 - 就像哪个存储属于哪个分支。 (git
可以对此有所帮助,但它仍然很容易搞砸。)所以另外要考虑的解决方案:
您的仓库可以有多个工作树,每个工作树对应一个不同的分支。
git worktree add /path/for/additional/worktree branch
请参阅git worktree
文档。
现在,您可以在文件系统的不同路径上同时使用该文件的两个版本,因此任何工具都可以&#34;参见&#34;并在其中一个或两个上运作。
这可以说是对你所要求的最灵活的解释,但如果其他解决方案足够好并且#34;那么这可能是过度的。为您的用例。