我认为git日志在那里,因此您可以检查所有历史记录并准确查看发生了什么变化在哪里,但是挤压它会将其退出历史记录,并将其全部合并为一次提交。这有什么意义?
这似乎也违背了“提早提交并经常提交”的口头禅。
#1 楼
这样您就可以拥有清晰明了的git历史记录,从而清楚,轻松地记录所做的更改及其原因。例如,对于我来说,典型的“未压缩” git日志可能如下所示:
7hgf8978g9... Added new slideshow feature, JIRA # 848394839
85493g2458... Fixed slideshow display issue in ie
gh354354gh... wip, done for the week
789fdfffdf... minor alignment issue
787g8fgf78... hotfix for #5849564648
9080gf6567... implemented feature # 65896859
gh34839843... minor fix (typo) for 3rd test
真是一团糟!
而更仔细地管理和合并的git日志,而对消息的关注则可能看起来像这样:
7hgf8978g9... 8483948393 Added new slideshow feature
787g8fgf78... 5849564648 Hotfix for android display issue
9080gf6567... 6589685988 Implemented pop-up to select language
我认为您通常可以看到提交提交的问题,并且相同的原则也适用于请求请求-历史的可读性。您可能还会向已经有数百甚至数千次提交的提交日志中添加内容,这将有助于使不断增长的历史变得简明扼要。
您希望经常提早提交。出于多种原因,这是最佳做法。我发现这导致我经常使用“ wip”(进行中的工作)或“ A部分完成”或“ typo,次要修复”的提交,这些提交是我使用git来帮助我工作并提供工作要点的我可以回到下面的代码无法正常工作的过程中。但是,我不需要或不希望将该历史记录作为最终git历史记录的一部分,因此可以压缩自己的提交-但请参阅以下注释,以了解这对开发分支与master意味着什么。
是代表不同工作阶段的主要里程碑,每个功能/任务/错误不止一次提交也是可以的。但是,这通常可以凸显以下事实:正在开发的票证“太大”,需要分解成可以独立的小块,例如:
8754390gf87... Implement feature switches
好像是“一件工作”。它们要么存在,要么不存在!打破它似乎没有任何意义。但是经验表明,(取决于组织的规模和复杂性)更细粒度的路径可能是:
fgfd7897899... Add field to database, add indexes and a trigger for the dw group
9458947548g... Add 'backend' code in controller for when id is passed in url.
6256ac24426... Add 'backend' code to make field available for views.
402c476edf6... Add feature to UI
小片段意味着更容易的代码审查,更容易的单元测试,更好的质量保证机会,更好的与单一职责原则保持一致等。有自己的工作流程
您的开发,例如拉取请求
您的工作已添加到主线分支中,例如掌握
在开发过程中,您“尽早且经常”提交信息,并带有快速的“一次性”信息。有时您可能希望在这里压扁挤压wip和todo消息提交。可以在分支内保留代表您在开发中所采取的不同步骤的多个提交。您选择要做的大多数南瓜都应该在这些要素分支中,而这些要素正处于开发过程中,并且在合并到母版之前。
当添加到主线分支时,您希望提交内容简洁明了,并根据格式正确设置现有主线历史记录。这可能包括Ticket Tracker系统ID,例如JIRA如示例所示。除非您要在主数据库上“汇总”几个不同的提交,否则在这里并不是真正需要压榨。通常您不会。
在合并到master时使用
--no-ff
将使用一次提交进行合并,并保留历史记录(在分支中)。一些组织认为这是最佳做法。在https://stackoverflow.com/q/9069061/631619上查看更多信息。您还将在git log
中看到实际的效果,其中--no-ff
提交将是最新提交,位于HEAD的顶部(刚刚完成时),而没有--no-ff
它可能会在历史记录中进一步下降,具体取决于日期和其他提交。评论
我完全不同意这种哲学。小型常规提交将任务分解为较小的任务,并且经常准确地提供有关更改行时正在处理的内容的有用信息。如果您有少量的“ WIP”提交,则应在推送之前使用交互式的基准库对其进行清理。压缩PR似乎完全击败了常规的小型提交恕我直言。对于努力提供带有特定提交信息的日志消息的作者来说,这几乎是不敬的,您只需将其全部丢弃即可。
–杰兹
18-2-6在11:44
有趣。归根结底,我的“哲学”基于我所看到的作品。需要明确的是,在进行变更时,将工作分解成小部分并投入每一部分是很棒的。我的经验是,一旦将这项工作合并到母版中,往往要检查的主要内容是“什么,通常是导致问题x的合并提交是什么?
–迈克尔·杜兰特(Michael Durrant)
18年2月6日在17:26
我也是防南瓜。首先,您不应该编写愚蠢的提交消息。在示例中(85493g2458 ...修复了ie中的幻灯片显示问题),如果我要调试与其关联的代码,这将大有帮助。
–托马斯·戴维斯(Thomas Davis)
18-3-29在3:28
不幸的是,在SCM实践中出现了这种粗心和错位的教条。应该使用过滤工具来管理历史记录的可读性而不是提交行为。
–ctpenrose
18年11月27日在23:01
令人不安的趋势和教条。 y我希望以更合意的方式提出基于事实的论点。欢迎您发表/投票提出不同的意见。这就是社区投票的重点
–迈克尔·杜兰特(Michael Durrant)
18-11-28在2:34
#2 楼
因为拉动PR的人通常关心提交“添加的功能X”的最终效果,而不是“基本模板,错误修复功能X,添加功能Y,注释中的固定错别字,调整的数据缩放参数,散列图性能优于list“ ...详细程度如果您认为16次提交最好用2次提交而不是1次“添加功能X,将Z重构为使用X”来最好地表示,那可能很好提出一个具有2个提交的公关,但是在这种情况下,最好是提议两个单独的pr(如果回购协议仍然坚持单次提交pr)
这与“ commit”不冲突尽早提交并经常提交”的口头禅,就像在回购中一样,在开发过程中,您仍然具有详细的细节,因此您失去工作的机会很小,并且其他人可以在新PR出台时针对您的工作进行审核/提出/提出PR。正在开发中。
评论
但是,当您壁球提交时,您也会在叉子中丢失该历史记录,对吗?您为什么要放弃那个历史?
– hamstar
2014年11月18日23:43
a)如果您想保留分支中的历史记录,可以轻松地创建一个“ for merge”分支和一个“ dev”分支(无论如何,这都是您所需要的,因为您可以向主开发中添加新的提交)提出PR后分支)b)您仍然保留那些提交的最终结果,只有在您希望撤消或选择PR的子组件的情况下,才需要单个提交。在这种情况下,您可能在单个PR中执行多项操作(例如:错误修正X,添加功能Y),并且可能再次需要多个PR。
–安德鲁·希尔(Andrew Hill)
2014-11-19 0:00
@AndrewHill多么伟大的概念!我想将这个工作流程介绍给我的团队,它对您有什么帮助?我写了一篇关于它的博客文章,并在研究它时遇到了这个评论。
– Droogans
15年7月25日在8:29
保留历史记录(不压缩提交)和使用拉取请求都支持两种用例:详细信息在原始提交中可用;仅检查合并提交即可读取高级历史记录,例如通过执行git log ---通过装饰简化。
– Arialdo Martini
3月6日13:59
一旦回购到一定规模,几乎每个要查看回购协议的人都只会在乎高级历史。
–安德鲁·希尔(Andrew Hill)
4月30日下午2:27
#3 楼
从我看到的主要原因如下:当前用于合并请求请求的GitHub UI(2015年10月)不允许您编辑提交消息的第一行,强制为
Merge pull request #123 from joebloggs/fix-snafoo
当前用于浏览提交历史记录的GitHub UI不允许您从
--first-parent
的角度查看分支的历史记录用于查看当前责备文件不允许您以
--first-parent
的角度查看文件责备(请注意,这仅在Git 2.6.2中已修复,因此我们可以原谅GitHub没有可用的责备)因此,当您将上述所有三种情况结合在一起时,您会遇到一种情况,即从GitHub UI合并未压缩的提交看起来很丑。
您的压缩历史记录看起来像是
/>
1256556316... Merge pull request #423 from jrandom/add-slideshows
7hgf8978g9... Added new slideshow feature
56556316ad... Merge pull request #324 from ahacker/fix-android-display
787g8fgf78... Hotfix for android display issue
f56556316e... Merge pull request #28 from somwhere/select-lang-popup
9080gf6567... Implemented pop-up to select language
未压缩提交的历史记录将类似于
1256556316... Merge pull request #423 from jrandom/add-slideshows
7hgf8978g9... Added new slideshow feature, JIRA # 848394839
85493g2458... Fixed slideshow display issue in ie
gh354354gh... wip, done for the week
789fdfffdf... minor alignment issue
56556316ad... Merge pull request #324 from ahacker/fix-android-display
787g8fgf78... hotfix for #5849564648
f56556316e... Merge pull request #28 from somwhere/select-lang-popup
9080gf6567... implemented feature # 65896859
gh34839843... minor fix (typo) for 3rd test
当y您可能会在PR跟踪中提交大量内容,如果您限制自己使用GitHub UI,那么所做的更改可能会有些噩梦。
例如,您发现在文件中某处取消引用了空指针...,所以您说“这是谁创建的,什么时候?什么发行版本受到影响?”。然后,您转到GitHub UI中的blame视图,然后看到在
789fdfffdf
中更改了该行……“哦,请稍等,该行只是将其缩进更改为适合其余的代码” ,因此现在您需要在父提交中导航至该文件的树状状态,然后重新访问非常规页面...最终找到该提交...这是6个月前的提交...“哦** **这可能会影响6个月的用户。“您说...啊,但是,等一下,那个提交实际上是在请求请求中,直到昨天才被合并,还没有人削减发行版...”该死的人们正在合并提交“没有挤压历史”是通常在通过GitHub UI进行大约2或3次代码考古学考察之后可以听到的呐喊现在,让我们考虑一下如果您使用Git命令行(以及超级-很棒的2.6.2,具有
git blame --first-parent
的修复程序)如果您使用的是Git命令行,则可以控制合并提交消息完全合并,因此合并提交可以有一个不错的摘要行。
所以我们的提交历史看起来像
$ git log
1256556316... #423 Added new slideshow feature
7hgf8978g9... Added new slideshow feature, JIRA # 848394839
85493g2458... Fixed slideshow display issue in ie
gh354354gh... wip, done for the week
789fdfffdf... minor alignment issue
56556316ad... #324 Hotfix for android display issue
787g8fgf78... hotfix for #5849564648
f56556316e... #28 Implemented pop-up to select language
9080gf6567... implemented feature # 65896859
gh34839843... minor fix (typo) for 3rd test
但是我们也可以做
$ git log --first-parent
1256556316... #423 Added new slideshow feature
56556316ad... #324 Hotfix for android display issue
f56556316e... #28 Implemented pop-up to select language
(换句话说:Git CLI允许您吃蛋糕也可以吃)
现在当我们按下空指针时问题...好吧,我们只使用
git blame --first-parent -w dodgy-file.c
,我们会得到确切的提交,其中将空指针取消引用引入到master分支,而忽略了简单的空格更改。当然,如果您要进行合并使用GitHub UI,则由于GitHub强制执行合并提交消息的第一行,所以
git log --first-parent
实在太糟糕了:1256556316... Merge pull request #423 from jrandom/add-slideshows
56556316ad... Merge pull request #324 from ahacker/fix-android-display
f56556316e... Merge pull request #28 from somwhere/select-lang-popup
因此,总而言之,简短地说:
GitHub UI(2015年10月)在合并合并请求,如何显示提交历史记录以及如何归咎于责备信息方面存在许多缺陷。解决GitHub UI中这些缺陷的当前最佳方法是在合并之前要求人们压缩提交。
Git CLI没有这些问题,您可以轻松地选择要查看的视图,以便双方都能找到以这种方式进行特定更改的原因(通过查看历史记录)并查看有效压缩的提交。
Post Script
经常引用压缩提交的最终原因是使向后移植更容易...如果您只需向后端口提交一次提交(即压缩的提交),就可以很容易地选择樱桃...
好吧,如果您正在查看带有
git log --first-parent
的git历史记录,那么您可以只选择樱桃合并提交。大多数人会感到困惑,因为必须指定-m N
选项,但是如果您从git log --first-parent
获得了提交,则您知道它是您要遵循的第一个父级,因此它将是git cherry-pick -m 1 ...
评论
好答案!但是挑选一个范围很容易,不确定我是否会买它。
–斯蒂格勒
16年8月1日,下午3:54
@stiggler我个人不购买它是有原因的,但是我认为它被其他人引用是有原因的。恕我直言,git工具就是您想要的,并且挤压提交是邪恶的……但是我要说的是,我自己推动了--first-parent的修复,以便赢得反对挤压提交的论点;-)
–斯蒂芬·康诺利(Stephen Connolly)
16年8月2日在12:57
这应该是公认的答案。教条要少得多,它表明历史过滤可以用来“吃蛋糕也吃”。您无需消灭历史就可以使git历史探索变得清晰。
–ctpenrose
18年11月28日在0:07
如果通过挤压提交最终导致将对不同文件的许多更改分组到一个提交中,那么选择樱桃并不是那么容易。我猜这会根据代码库,进行了哪些更改,正在协作的人数等等而有很大不同。我认为我们无法提出一条通用规则在所有情况下均有效。
–艾米·佩莱格里尼(Amy Pellegrini)
19年6月12日在11:12
#4 楼
我会看看代码是否公开。当项目保持私有时:
我建议不要压扁,看看香肠的制作方法。如果您使用好的提交和小的提交,则git bisect之类的工具非常方便,人们可以快速查明回归提交,并查看您为什么这样做(由于提交消息)。
项目公开时:
压缩所有内容,因为某些提交可能包含安全漏洞。例如,已提交并再次删除的密码。
评论
阿们在我职业生涯的早期,发生了以下事情。我花了一个星期来调试一些与硬件有关的怪癖代码。我喜欢那时的基地。因此,在我再次不小心破坏了代码之后,刷新日志受到了严重污染,以至于找不到绿点。将提交视为不可变(大多数情况下)可以减轻这种情况。
– Vorac
8月8日下午6:32
#5 楼
我同意在此主题的其他答案中表达的关于显示清晰简洁的已添加功能和已修复错误的历史的观点。但是,我确实想解决您的问题未曾提及但未明确陈述的另一个方面。与git的某些工作方法有关的部分挂断是git允许您重写历史记录,当使用其他形式的源代码控制(无法执行此类操作)后,将其引入git时似乎很奇怪。此外,这还违反了源代码管理的普遍接受原则,即一旦将某些内容提交/签入到源代码管理中,则无论您在提交之后进行了什么更改,都应该能够恢复到该状态。正如您在问题中暗示的那样,这是其中一种情况。我认为git是一个很棒的版本控制系统;但是,要了解它,您必须了解一些实现细节和背后的设计决策,因此它的学习曲线更陡峭。请记住,git旨在成为一个分布式版本控制系统,这将有助于解释为什么设计人员允许使用南瓜提交重写git历史,这就是一个例子。评论
严格来说,Git不允许您更改历史记录。提交对象是不可变的。只有可变的分支指针,然后才具有“强制更新”,这通常被认为是您仅出于开发目的而不是在master分支上执行的操作。您始终可以使用reflog返回以前的状态,除非已运行git gc来丢弃未引用的对象。
–琼·普迪(Jon Purdy)
2014年11月22日在22:37
您是正确的,也许我应该在上面提到这一点。但是,我会争辩说已经被推送到远程回购中的诸如强行推送或变基提交之类的事情将被视为重写历史,因为提交的顺序和排列与提交本身一样重要。
–弗雷德·汤姆森(Fred Thomsen)
2014年11月23日4:00
对于给定的提交,这是正确的。在较大的图中,我认为交互式重新基准化和筛选器分支通过更改其组成有效地重写了历史。
–迈克尔·杜兰特(Michael Durrant)
2014年11月23日15:14
公平地说,SVN保持“每次提交都是神圣的”方法,但是在合并时,使用该合并创建一个提交,并隐藏对此做出贡献的修订,因此似乎所有SVN合并都是“基于基础的”。它们不是,您只需要告诉history命令向您显示合并的组件即可。我最喜欢这种方法。
– gbjbaanb
15年7月23日在7:32
#6 楼
由于观点...最佳实践是,如果可能的话,对每个<<issue-management-system>>
问题进行一次提交。 您可以在自己的功能分支/存储库中进行任意数量的提交,但是从您的角度来看,这与您现在正在做的事情有关,因此...与历史无关从他们的角度来看,整个TEAM / PROJECT或应用程序要保留几个月,因此...
因此,无论何时您想将错误修复或功能提交到通用存储库中(此示例与分支),您可以按照以下步骤进行操作:
如何将您的功能分支重新建立基础以快速开发
# set your current branch , make a backup of it , caveat minute precision
curr_branch=$(git rev-parse --abbrev-ref HEAD); git branch "$curr_branch"--$(date "+%Y%m%d_%H%M"); git branch -a | grep $curr_branch | sort -nr
# squash all your changes at once
git reset $(git merge-base develop $curr_branch)
# check the modified files to add
git status
# add the modified files dir by dir, or file by file or all as shown
git add --all
# check once again
git log --format='%h %ai %an %m%m %s' | less
# add the single message of your commit for the stuff you did
git commit -m "<<MY-ISSUE-ID>>: add my very important feature"
# check once again
git log --format='%h %ai %an %m%m %s' | less
# make a backup once again , use seconds precision if you were too fast ...
curr_branch=$(git rev-parse --abbrev-ref HEAD); git branch "$curr_branch"--$(date "+%Y%m%d_%H%M"); git branch -a | grep $curr_branch | sort -nr
# compare the old backup with the new backup , should not have any differences
git diff <<old-backup>>..<<new-backup-branch>>
# you would have to git push force to your feature branch
git push --force
评论
这甚至都没有尝试解决所问的问题,为什么壁球git提交拉取请求?查看如何回答
– gna
18年4月10日在10:34
在尝试解释之后,应该这样做...
–约旦·格奥尔基耶夫(Yordan Georgiev)
18年4月10日在10:56
我不知为何看不到添加的解释如何提供超过几年前发表的最高投票答案中提出和解释的要点的实质内容(尽管对改进第一版的努力表示赞赏)
– gna
18年4月10日在11:05
关键字是“视角”,视角概念使在IT中解释此类问题更加容易,例如-您对这个问题的答案的视角已经提供,我的视角是使用“视角”关键字并提供了一个实际的示例,说明了如何通过不同的角度来解释如何实现最佳实践……
–约旦·格奥尔基耶夫(Yordan Georgiev)
18年4月10日在11:39
评论
对于大型仓库,当人们想对仓库进行任何操作时,它可以节省大量的时间和空间。“这似乎也违背了“提早提交并经常提交”的口头禅。 -不,您确实会提早/经常做出承诺,但是您不一定要PR每一个微小的更改。而且审稿人也不想翻阅它们,这是肯定的。
无需对问题进行编辑即可总结出感知的答案是什么。那是公认的答案和赞誉的地方。人们可以通过阅读答案得出自己的结论。
我仍然不明白为什么要压缩提交。我认为有太多弊端要压倒几乎没有利弊。这是一个伪装成数据问题的演示文稿问题。
日志上所有有用的分析都会丢失。因此,似乎开发人员只需一次提交即可完成一项功能。很难理解为什么存在奇数段代码。功能的历史可能很重要,并且可以在很大程度上解释代码为何如此。日志的简洁视图很有用,但是不能以其他方式实现吗?