学分布式的时候我就知道,如果 a 直接到 b ,那么中间加一层 c ,a 到 c ,c 到 b 这样就很灵活,我猜 git 中间加一层应该是有原因的
1
xuzhzzz 2022-01-17 10:37:05 +08:00
一看就是 git add . 用多了 (我也是)
|
2
wangxn 2022-01-17 10:40:10 +08:00 via Android
git add -p 就需要这个状态。冲突状态应该也算是它的一个变种吧。
我的理解它就是一个可以让用户整理和准备一个 commit 的中间状态,已经想不起 SVN 这些没有这个状态的工作流程是啥了。 |
3
irobbin 2022-01-17 10:41:33 +08:00
想把 git 用的精细就需要暂存区
|
4
mrgeneral 2022-01-17 10:43:02 +08:00 1
避免无效 commit:本次改动还没写完,但是要临时切换分支去 fix bug 、处理问题等等,需要把本次工作内容暂时缓存下来。
当然你也可以直接先 commit 到分支,但是会导致 commit 记录就很乱,或者得再花其他精力去 rebase 之类的操作治理分支(不过随意 commit 的人也不会有这个意愿 /狗头)。 |
5
Xbluer 2022-01-17 10:46:53 +08:00
参考数据库设计,为了保证数据的一致性,需要一次修改多张表的字段,所以引入了事务这个概念。
同样的,修改代码很多时候也需要修改多个文件的。比如修改了一个方法名,那么其他文件中调用了这个方法的地方都需要同步修改掉。 |
6
gengchun 2022-01-17 11:02:08 +08:00
这个要和早期的 patch 这种工作流和内核那种大型项目联系起来。有的时候需要把一堆的 patch 文件切分成多个 commit ,必须要用 staging area 。
切分支什么的,反正可以后面 push 前再 rebase 。而且大部分切分支的情况还是本地的分支,所以并不是一定要用到暂存。 现代一点的工作流,或者不是很复杂的代码库,唯一常用的情况估计只有解决分支合并时的冲突这种。其它情况都不是必须。 |
7
GuuJiang 2022-01-17 11:09:10 +08:00 via iPhone 2
假设没有暂存区,就相当于 commit(file1, file2, file3, …);
而有了暂存区,就相当于 stage.add(file1); stage.add(file2); stage.add(file3); commit(stage); 说白了就是提供一种对命令行下交互友好的“选择待提交文件的操作” |
8
2i2Re2PLMaDnghL 2022-01-17 11:17:27 +08:00 1
@mrgeneral 我感觉 OP 说的是 stage ,你说的这是 stash
|
9
misaka19000 2022-01-17 11:22:43 +08:00 1
暂存区?是指 git add 之后的内容?中文怎么感觉这么别扭。。
这个很简单,因为 command 没有选中的功能,假设修改了两个文件 A 和 B ,不借助 add 命令不能做到只提交一个文件 |
10
gps949 2022-01-17 11:25:28 +08:00
封控区、管控区、防控区
|
11
fly2mars 2022-01-17 11:37:10 +08:00
暂存是真方便 甚至还单独设置了快捷键 经常开发中途要改 bug 那就先把手上的暂存了 去改 bug 改完又 pop 出来
|
12
fengci 2022-01-17 11:49:47 +08:00
暂存挺好的, 本来开发需求中,临时来了紧急需求,用暂存先保留之前的代码。切回原来代码开发提交后 。再找回暂存数据继续开发
|
13
godmiracle 2022-01-17 12:04:50 +08:00
防止突发需求啊。。你手头上的活一个功能没完,你总不能直接 git add 吧
|
14
uni 2022-01-17 13:06:43 +08:00
你说的是 stage 还是 stash
stash 很有用的,就是手上的事情做一半要去做其他事情,那就把手上的事情 stash ,其他事情做完了在 pop 原来的事情回来继续 至于 stage ,想起来当时刚接触 git 的时候也有疑问,后来用多了就逐渐忘记了……现在要我说的话,我觉得 stage 的作用就是给一个地方让你把你要提交的东西收集起来一起提交,不过实践中很多时间就直接 git commit -am 直接提交了…… |
16
clrss 2022-01-17 13:11:33 +08:00
应该就是上面说的方便命令行操作.
GUI 如 JetBrains IDE, cmd-K 然后打勾就行. 流程里确实没有 stage 的概念. |
17
yuedashi 2022-01-17 13:17:16 +08:00 via Android
用过 git add -p 就知道为啥了。还有谁说命令行必须 git add 才能提交?可以直接 git commit file file2
|
18
einq7 2022-01-17 13:58:17 +08:00
到底是指 git add 的,还是 stash 的
|
19
gromit1337 2022-01-17 14:06:05 +08:00 1
楼主说的是 stage 贴里一半的人在说 stash
|
20
baiyi 2022-01-17 14:39:31 +08:00 2
推荐看看 《 Pro Git 》,里面有很好的解释。
Git 的每次 commit 其实是要求原子性的,就是说它应该是一个尽可能小量的不可切分的整体。但实际使用过程中,总会不可避免的修改到不需要在这个 commit 中存在的内容,此时就需要使用 git add 把需要的内容放在暂存区,git 内部称为“索引( index )”,这个索引指明了这次提交需改的内容,它能帮助我们挑选出本次 commit 要修改的内容,区分粒度也不是文件级的。 |
21
dddd1919 2022-01-17 14:54:01 +08:00
相当于商城里的购物车
|
22
Haixiang 2022-01-17 15:13:01 +08:00
具个例子:假如你此时在开发 Button 组件,但是开发着开发着发现 Navigation 组件有个特别小特别小的 Bug ,比如说写了个双等号,要改成三等号。
如果有没有中间的 Stage ,你就必须写完 Button 再改 Navigation ,或者先改 Navigation 再开发 Button 。 如果有中间态,那你可以两个都同时改了,提交的时候选 Button 的文件提交,再选 Navigation 的改动提交,变变成两次很清晰的提交,而不是像 git commit -a 无脑提交,别人 Review 代码的时候就会纳闷:你开发个 Button ,搞 Navigation 干嘛。 总的来说,git stage 可以让 git 操作更加精细,也就你说的灵活。当然这也只是 stage 的一个好处,还有在做 git diff 时也是很有帮助的。 |
23
leafre 2022-01-17 15:49:45 +08:00
预期的下一次提交
|
24
gadfly3173 2022-01-17 17:44:28 +08:00
@clrss #16 打勾其实就是 stage 了
|
25
chenliangngng 2022-01-17 20:20:48 +08:00
一个经常用的例子:
新建了一个文件 git add . git stash 这样可以把新文件放到 stash 里面,如果没有暂存区,那是放不进的 |
26
maplerecall 2022-01-17 21:07:38 +08:00 via Android
简单的说,实践过程中很多时候不是所有的改动都需要 commit 的,例如偶尔本地写死一个值或者修改一个配置用于调试。所以 commit 的时候难免需要选择部分而不是全部改动,这些选出的就被放在 stage 这个暂存区里了。
|
27
18000rpm 2022-01-17 23:49:20 +08:00
https://softwareengineering.stackexchange.com/questions/119782/what-does-stage-mean-in-git#comment318087_119790
https://stackoverflow.com/questions/4878358/why-would-i-want-stage-before-committing-in-git#comment71149979_4878399 看过一些相关讨论,讨论重点无非是需要保证每个 commit 的完整和纯粹。但是这个需求其实根本不用中间加个 stage 区也能在提交时保证。 有一个有用的场景是:git 的这套流程能实现只 commit 半个文件。例如在 git add 一些文件后,又对这些文件做了修改,而这些改动可能不属于本次 commit 的范围,这时 git 靠这个 stage 区就能实现半个文件的提交。从而保证了 commit 的纯粹。 但问题是这样的场景很常见吗? 更有一个新问题:在这套操作下,stage 区已经有文件与工作区不一致了,而 stage 区的文件是在测试代码和语法检测器测试范围之外的。在这种情况下 commit 的操作值得提倡吗? |
28
kidonng 2022-01-18 00:24:35 +08:00
Staging is commit action without commit identity
把 stage 当作轻量、无负担的 commit 就行 |
29
AItsuki 2022-01-18 01:07:27 +08:00
以前还真没想过这种问题,大多数使用场景中确实是可以忽略暂存区的,特别是用 idea 开发的人估计都勾选了自动暂存这个功能。
不过暂存区确实也有好用的地方,比如我写好一段代码,可以先添加到暂存区,然后又对这段代码进行尝试性优化。优化有效果就重新添加到暂存区,否则我可以直接舍弃掉当前工作区的代码然后直接提交。 又或者你写了一大堆垃圾代码,你只想保留其中一两个文件,你可以先将它们添加到暂存区,然后直接 git clean…… 还有一个很少用的功能就是,你对一个文件修改了多行代码,但你可以只添加其中一行到暂存区。 说白了就是暂存区能更灵活的控制提交的东西吧,你说这功能不是必要的话确实可能是不必要的,但我需要这功能,并且觉得很好用 XD |
30
dangyuluo 2022-01-18 03:15:56 +08:00
这就是设计哲学了,不懂
|
31
Rocketer 2022-01-18 03:23:43 +08:00 via iPhone
滥用 commit 的路过。
我从来都是原子提交,改完一个不可分割的小部分就提交一次,哪怕只改了一个备注,以便记录自己干了点啥。 如果需要临时切到别的分支,比如突然来了一个 bug 需要加急,那我也会提交一次,记录一下自己正在干什么,还有哪些准备做还没做的。因为我也不知道啥时候能回到这个分支,万一时间比较长,只是暂存的话就忘了该干啥了。 所以我不需要暂存区。 |
32
xiadong1994 2022-01-18 04:44:59 +08:00 via iPhone
@Rocketer 如果是 fork+pr+squash merge 的话,开发分支的 commit 记录其实无所谓
|
34
msg7086 2022-01-18 06:24:17 +08:00
我算是比较常用 Stage 的。经常会遇到一个文件里只需要提交其中几行代码的情况。用 Stage 就可以把其中的几行 Stage 起来然后提交,然后再把剩下的东西再做一次提交。
像楼上那样原子提交也是类似的效果,但是回头整理这些原子提交的时候一样要花时间。用 Stage 算是两者折中。 |
35
yuezk 2022-01-18 09:08:46 +08:00
@misaka19000 #9
> 这个很简单,因为 command 没有选中的功能,假设修改了两个文件 A 和 B ,不借助 add 命令不能做到只提交一个文件 这个不太准确,git commit 后面加要提交的文件是可以做到只提交某个或者某些文件的 |
36
sagaxu 2022-01-18 09:13:29 +08:00 via Android
你买买买不还得有个购物车?
|
37
42is42is42 2022-01-18 10:28:28 +08:00
|
38
sutra 2022-01-18 11:12:21 +08:00
stage 是为了 commit 更加原子性,不要在一个 commit 里包含多个功能。
|
40
rqtq 2022-01-18 11:33:08 +08:00
手上有很多任务时候,切来切去的时候很有用的
|
41
yuezk 2022-01-18 11:33:23 +08:00
@ink19 #39 只是想说明一下 git commit 是支持指定提交的文件的,而不用先运行 git add 。日常中比较常用的有 git commit . 和 git commit + 单个文件,还有 git commit + 通配符。
|
42
iugo 2022-01-18 12:31:42 +08:00
我常用的一种情况:
在做主要工作. 顺手改了部分代码, 没完成, 暂时不想提交. 我希望顺手的这部分保留, 但现在不要影响主要工作. |
43
hutusi 2022-01-18 12:58:57 +08:00
之前写另一篇关于 Git 的文章,希望对你有帮助: https://hutusi.com/articles/the-greatest-git-commit
|