为什么在提交 Git 之前需要 stage ?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4878358/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why would I want stage before committing in Git?
提问by Citizen
I'm new to version control and I understand that "committing" is essentially creating a backup while updating the new 'current' version of what you're working on.
我是版本控制的新手,我知道“提交”本质上是在更新您正在处理的新“当前”版本的同时创建备份。
What I don't understand is what staging for is from a practical perspective. Is staging something that exists in name only or does it serve a purpose? When you commit, its going to commit everything anyway, right?
我不明白的是,从实践的角度来看,登台是为了什么。上演是名义上存在的东西还是有目的的?当您提交时,它无论如何都会提交所有内容,对吗?
Edit: I think I may be confusing the terminology. Is a 'staged' file the same thing as a 'tracked' file?
编辑:我想我可能会混淆术语。“暂存”文件与“跟踪”文件是否相同?
采纳答案by Ben Hymanson
When you commit it's only going to commit the changes in the index (the "staged" files). There are many uses for this, but the most obvious is to break up your working changes into smaller, self-contained pieces. Perhaps you fixed a bug while you were implementing a feature. You can git add
just that file (or git add -p
to add just part of a file!) and then commit that bugfix before committing everything else. If you are using git commit -a
then you are just forcing an add
of everything right before the commit. Don't use -a
if you want to take advantage of staging files.
当您提交时,它只会提交索引(“暂存”文件)中的更改。这有很多用途,但最明显的是将您的工作更改分解为更小的、独立的部分。也许您在实现功能时修复了错误。您可以git add
只git add -p
添加该文件(或仅添加文件的一部分!),然后在提交其他所有内容之前提交该错误修复。如果您正在使用,git commit -a
那么您只是add
在提交之前强制执行所有内容。-a
如果您想利用暂存文件,请不要使用。
You can also treat the staged files as an intermediate working copy with the --cached
to many commands. For example, git diff --cached
will show you how the stage differs from HEAD
so you can see what you're about to commit without mixing in your other working changes.
您还可以使用--cached
to many 命令将暂存文件视为中间工作副本。例如,git diff --cached
将向您展示阶段的不同之处,HEAD
以便您可以查看将要提交的内容,而不会混入其他工作更改。
回答by Tapashee Tabassum Urmi
- Staging area gives the control to make commit smaller. Just make one logical change in the code, add the changed files to the staging area and finally if the changes are bad then checkout to the previous commit or otherwise commit the changes.It gives the flexibility to split the task into smaller tasks and commit smaller changes. With staging area it is easier to focus in small tasks.
- It also gives you the offer to take break and forgetting about how much work you have done before taking break. Suppose you need to change three files to make one logical change and you have changed the first file and need a long break until you start making the other changes. At this moment you cannot commit and you want to track which files you are done with so that after coming back you do not need to try to remember how much work have been done. So add the file to the staging area and it will save your work. When you come back just do
git diff --staged
and check which files you changed and where and start making other changes.
- 暂存区可以控制使提交更小。只需在代码中进行一个逻辑更改,将更改的文件添加到暂存区,最后如果更改不正确,则签出到之前的提交或以其他方式提交更改。它提供了将任务拆分为更小的任务并提交更小的灵活性变化。有了集结区,更容易专注于小任务。
- 它还为您提供休息的机会,让您忘记休息前做了多少工作。假设您需要更改三个文件以进行一个逻辑更改,并且您更改了第一个文件并且需要长时间休息,直到您开始进行其他更改。此时您无法提交,并且您想跟踪您完成了哪些文件,以便在回来后您无需尝试记住已经完成了多少工作。因此,将文件添加到暂存区,它将保存您的工作。当您回来时,只需
git diff --staged
检查您更改了哪些文件以及在哪里更改,然后开始进行其他更改。
回答by DarthWader
One practical purpose of staging is logical separation of file commits.
暂存的一个实际目的是文件提交的逻辑分离。
As staging allows you to continue making edits to the files/working directory, and make commits in parts when you think things are ready, you can use separate stages for logically unrelated edits.
由于暂存允许您继续对文件/工作目录进行编辑,并在您认为准备就绪时分部分提交,因此您可以使用单独的阶段进行逻辑上不相关的编辑。
Suppose you have 4 files fileA.html
, fileB.html
, fileC.html
and fileD.html
. You make changes to all 4 files and are ready to commit but changes in fileA.html
and fileB.html
are logically related (for example, same new feature implementation in both files) while changes in fileC.html
and fileD.html
are separate and logically unrelated to previous to files. You can first stage files fileA.html
and fileB.html
and commit those.
假设你有4个文件fileA.html
,fileB.html
,fileC.html
和fileD.html
。您对所有 4 个文件进行了更改并准备提交,但是fileA.html
和fileB.html
中的更改在逻辑上是相关的(例如,两个文件中的相同新功能实现),而fileC.html
和fileD.html
中的更改是独立的,并且与之前的文件在逻辑上无关。您可以第一阶段的文件fileA.html
和fileB.html
并提交这些。
git add fileA.html
git add fileB.html
git commit -m "Implemented new feature XYZ"
Then in next step you stage and commit changes to remaining two files.
然后在下一步中,您暂存并提交对其余两个文件的更改。
git add fileC.html
git add fileD.html
git commit -m "Implemented another feature EFG"
回答by Cibin Joseph
It is easier to understand the use of the git commands add
and commit
if you imagine a log file being maintained in your repository on Github.
A typical project's log file for me may look like:
这是比较容易理解的使用Git命令的add
和commit
如果你想像被保持在Github上你的资料库的日志文件。我的典型项目日志文件可能如下所示:
---------------- Day 1 --------------------
Message: Complete Task A
Index of files changed: File1, File2
Message: Complete Task B
Index of files changed: File2, File3
-------------------------------------------
---------------- Day 2 --------------------
Message: Correct typos
Index of files changed: File3, File1
-------------------------------------------
...
...
...and so on
I usually start my day with a git pull
request and end it with a git push
request. So everything inside a day's record corresponds to what occurs between them. During each day, there are one or more logical tasksthat I complete which require changing a few files. The files edited during that task are listed in an index.
我通常以一个git pull
请求开始我的一天,并以一个请求结束它git push
。因此,一天记录中的所有内容都对应于它们之间发生的情况。在每一天,我都会完成一个或多个逻辑任务,这些任务需要更改一些文件。在该任务期间编辑的文件列在索引中。
Each of these sub tasks(Task A and Task B here) are individual commits. The git add
command adds files to the 'Index of Files Changed' list. This process is also called staging. The git commit
command records/finalizes the changes and the corresponding index list along with a custom message.
这些子任务(这里的任务 A 和任务 B)中的每一个都是单独的提交。该git add
命令将文件添加到“已更改文件索引”列表中。此过程也称为分期。该git commit
命令记录/完成更改和相应的索引列表以及自定义消息。
Remember that you're still only changing the local copy of your repository and not the one on Github. After this, only when you do a 'git push' do all these recorded changes, along with your index files for each commit, get logged on the main repository(on Github).
请记住,您仍然只更改存储库的本地副本,而不是 Github 上的副本。在此之后,只有当您执行“git push”时,才会将所有这些记录的更改以及每次提交的索引文件都记录到主存储库(在 Github 上)。
As an example, to obtain the second entry in that imaginary log file, I would have done:
例如,要获取该假想日志文件中的第二个条目,我会这样做:
git pull
# Make changes to these files
git add File3 File4
# Verify changes, run tests etc..
git commit -m 'Correct typos'
git push
In a nutshell, git add
and git commit
lets you break down a change to the main repository into systematic logical sub-changes. As other answers and comments have pointed out, there are ofcourse many more uses to them. However, this is one of the most common usages and a driving principle behind Git being a multi-stage revision control system unlike other popular ones like Svn.
简而言之,git add
它git commit
允许您将主存储库的更改分解为系统的逻辑子更改。正如其他答案和评论所指出的那样,它们当然还有更多用途。然而,这是最常见的用法之一,也是 Git 作为多阶段修订控制系统背后的驱动原则,这与 Svn 等其他流行的系统不同。
回答by Andrew Nessin
Staging area helps us craft the commits with greater flexibility. By crafting, I mean breaking up the commits into logical units. This is very crucial if you want a maintainable software. The most obvious way you can achieve this:
暂存区帮助我们以更大的灵活性制作提交。通过制作,我的意思是将提交分解为逻辑单元。如果您想要一个可维护的软件,这非常重要。您可以实现这一目标的最明显方法:
You can work on multiple features/bugs in a single working directory and still craft meaningful commits. Having a single working directory which contains all of our active work is also very convenient. (This can be done without a staging area, only as long as the changes don't ever overlap a file. And you also have the added responsibility of manually tracking whether they overlap)
您可以在单个工作目录中处理多个功能/错误,并且仍然可以制作有意义的提交。拥有一个包含我们所有活动工作的工作目录也非常方便。(这可以在没有暂存区的情况下完成,前提是更改不会与文件重叠。并且您还需要额外负责手动跟踪它们是否重叠)
You can find more examples here: Uses of Index
您可以在此处找到更多示例: 索引的使用
And the best part is, the advantages do not stop with this list of workflows. If a unique workflow does come up, you can be almost sure that staging area will help you out.
最好的部分是,优势并不止于此工作流列表。如果确实出现了独特的工作流程,您几乎可以确定临时区域会为您提供帮助。
回答by Ali80
I see the point on using stage to make commits smaller as mentioned by @Ben Hymanson and @Tapashee Tabassum Urmi and sometimes I use it for that purpose, but I mainly use it to make my commits larger! here is my point:
正如@Ben Hymanson 和@Tapashee Tabassum Urmi 所提到的,我看到了使用 stage 使提交变小的重要性,有时我将它用于此目的,但我主要使用它来使我的提交变大!这是我的观点:
Say I want to add a small feature which require several smaller steps. I don't see any point in having a separate commit for smaller steps and flooding my timeline. However I want to save each step and go back if necessary,
假设我想添加一个需要几个较小步骤的小功能。我认为为较小的步骤单独提交并淹没我的时间线没有任何意义。但是我想保存每一步并在必要时返回,
I simply stage the smaller steps on top of each other and when I feel it is worthy of a commit, I commit. This way I remove the unnecessary commits from the timeline yet able to undo(checkout) the last step.
我只是将较小的步骤相互叠加,当我觉得值得提交时,我会提交。通过这种方式,我从时间线中删除了不必要的提交,但能够撤消(结帐)最后一步。
I see other ways for doing this (simplifying the git history) which you might use depending on your preference:
我看到了执行此操作的其他方法(简化 git 历史记录),您可以根据自己的喜好使用这些方法:
- git amend (which changes your last commit) which is not something you want for this specific purpose (I see it mostly as doing a bad commit and then fixing it)
- git rebase, which is an afterthought and can cause serious problems for you and others who use your repository.
- creating a temporary branch, merge and then delete it afterwards(which is also a good option, requires more steps but gives your more control)
- git amend(它改变了你的最后一次提交)这不是你想要用于这个特定目的的东西(我认为它主要是做一个错误的提交然后修复它)
- git rebase,这是事后的想法,可能会给您和使用您的存储库的其他人带来严重问题。
- 创建一个临时分支,合并然后删除它(这也是一个不错的选择,需要更多的步骤,但给你更多的控制权)