简体   繁体   English

git工作流程:维护功能提交的历史记录

[英]git workflow: maintaining a history of functional commits

What is the best way to maintain a history of functioning versions of your git repository ? 维护git仓库功能版本历史的最佳方法是什么

It's so easy to branch and merge in git that we do it all the time. 在git中进行分支和合并非常容易,我们一直都在这样做。 I've generally taken to using topic branches, only merging into master when a feature is complete. 我通常会使用主题分支,仅在功能完成时才合并到master。 This works fine, but after several iterations the history of your master branch is a convoluted graph and it becomes very difficult to identify commits that represent a correctly functioning version of your application at any point in time. 这可以正常工作,但是经过几次迭代后,您的master分支的历史是一个复杂的图形,并且很难在任何时间点识别代表您的应用程序正常运行的版本的提交。

I'm looking for advice on a workflow that enables me to easily retrieve a working (ie not in the middle of developing a feature) copy of my repo closest to a specified date. 我正在寻找有关工作流的建议,该工作流使我能够轻松地检索到最接近指定日期的工作清单(即不在开发功能中)。 Another useful feature of this would be retrieving a list of commits that represent a functioning repository changing over time. 另一个有用的功能将是检索代表功能库随着时间变化的提交列表。

I realize this could be done manually ie examine the commit log and messages to find the last commit right before the next feature was started, or by running the test suite against each commit and filter by that. 我意识到这可以手动完成,即检查提交日志和消息以在下一个功能启动之前找到最后一个提交,或者通过针对每个提交运行测试套件并对其进行过滤。 Those methods would be somewhat reliable, but I'm looking for a less haphazard way of doing it. 这些方法在某种程度上是可靠的,但我正在寻找一种不太随意的方法。

You can use git log --first-parent master to see a history of master, following only the first parent of each commit. 您可以使用git log --first-parent master来查看git log --first-parent master的历史记录,仅在每次提交的第一个父节点之后。 This means that when a merge is encountered, only the first parent (which should be the previous commit on master) is followed, and the second parent (the last commit on the topic branch) is ignored. 这意味着在遇到合并时,仅遵循第一个父对象(应该是master上的上一次提交),而第二个父对象(主题分支上的最后一个提交)将被忽略。 With your workflow, this will likely consist of mostly merges. 对于您的工作流程,这很可能主要由合并组成。 The important point is, as long as any commit (or merge) made on master is considered a functioning version, then every single commit in this log is a functioning version. 重要的一点是,只要在master上进行的任何提交(或合并)都被认为是有效版本,那么此日志中的每个单个提交都是有效版本。

I am super glad to hear you using feature branches - go you :) 我很高兴听到您使用功能分支-去吧:)

After that, there are two ways to keep things tidy, and one thing that just helps your brain work better. 在那之后,有两种方法可以使事情保持整洁,一种可以帮助您的大脑更好地工作。

1) For each branch you are actively working on, make a local branch. 1)对于您正在积极工作的每个分支,请创建一个本地分支。 You want to do this because you want to be able to rebase what everyone else is doing. 您之所以要这样做,是因为您希望能够重新确定其他人在做什么。 Without the rebase you'll have a bunch of commits representing merges that really don't add anything to the history. 没有重新设置基准,您将有很多提交代表合并,而这些合并实际上并没有添加任何历史记录。 You can rebase the branch which is remote, however this is discouraged as rebasing rewrites history, and should two people do it at the same time - it gets hairy and really hard to follow. 您可以重新设置远程分支的基准,但是不建议重新建立历史记录,并且两个人应同时执行时,这是不鼓励的-它变得冗长,而且很难遵循。 Early on in projects I usually just work off master . 在项目初期,我通常只是master So I create a master_local which does not track anything (git branch master_local). 所以我创建了一个master_local ,它不跟踪任何内容(git分支master_local)。 When people make changes I want or need (git pull), while having master_local checked out, just rebase (git rebase master). 当人们做出我想要或需要的更改(git pull)时,在检出master_local同时,只需重新设置基准(git rebase master)。

And the tip to keep your brain working well - merge your local branch into the tracking/remote feature branch often. 以及保持大脑正常工作的技巧-经常将本地分支合并到跟踪/远程功能分支中。 The longer you keep things separated the more you'll have to remember, the larger your merge will be, the more others will be complaining that you're not working, etc. ;) 您将事物分开的时间越长,您将需要记住的越多,合并将越大,其他人将抱怨您不工作,等等;)

2) If you have large features and many people, you'll have tons of commits per feature branch. 2)如果您拥有大型功能并且有很多人,那么每个功能分支将拥有大量的提交。 Once these features are ready to get to master you just don't need to see all of it. 一旦准备好掌握这些功能,您就无需全部查看。 And if you want to revert the feature out you don't want to revert several hundred patches. 而且,如果您想还原该功能,则不想还原数百个补丁。 The answer to all of this is to squash your commits down to 1 single commit. 所有这些的答案是将您的提交压缩到1次单次提交。 This way master is a nice and short list of the features contained therein. 这种方式,母版是其中包含的功能很好的简短清单。 (http://www.gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html) (http://www.gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html)

I think the best solution (long-term) would be to adapt your workflow, to keep your master branch clean of intermediate 'checkpoint' commits. 我认为最好的解决方案(长期)是适应您的工作流程,使主分支保持中间的“检查点”提交不受影响。 Benjamin Sandofsky details a workflow that appears to stay closest to the way Git was designed. 本杰明·桑多夫斯基(Benjamin Sandofsky)详细介绍了工作流程该工作流程似乎最接近Git的设计方式。

The gist of the article: 文章的要旨:

Think of branches in two categories: public and private. 考虑两类分支:公共分支和私有分支。

Public branches are the authoritative history of the project. 公共分支机构是该项目的权威历史。 In a public branch, every commit should be succinct, atomic, and have a well documented commit message. 在公共分支中,每个提交都应简洁明了,原子化,并具有记录良好的提交消息。 It should be as linear as possible. 它应尽可能线性。 It should be immutable. 它应该是不变的。 Public branches include Master and release branches. 公共分支包括主分支和发布分支。 A private branch is for yourself. 私人分支机构适合您自己。 It's your scratch paper while working out a problem. 解决问题时,这是您的便条纸。

The no-ff band-aid, broken bisect, and blame mysteries are all symptoms that you're using a screwdriver as a hammer. 无用创可贴,断裂等分线和怪异之谜都是您使用螺丝刀锤子的症状。

You should never merge a private branch directly into a public branch with a vanilla merge. 绝对不要使用香草合并将私有分支直接合并到公共分支。 First, clean up your branch with tools like reset, rebase, squash merges, and commit amending. 首先,使用诸如重置,变基,压缩合并和提交修改之类的工具清理分支。 If you treat your public history as pristine, fast-forward merges are not only safe but preferable. 如果您将公开历史视为原始记录,那么快速合并不仅是安全的,而且是可取的。 They keep revision history linear and easier to follow. 它们使修订历史保持线性,更易于遵循。

Treat public history as immutable, atomic, and easy to follow. 将公共历史视为一成不变,原子化且易于遵循。 Treat private history as disposable and malleable. 将私人历史视为一次性和可延展的。

The intended workflow is: 预期的工作流程是:

  1. Create a private branch off a public branch. 从公共分支创建一个私有分支。
  2. Regularly commit your work to this private branch. 定期将您的工作提交到此私人分支。
  3. Once your code is perfect, clean up its history. 一旦代码完美,请清理其历史记录。
  4. Merge the cleaned-up branch back into the public branch. 将清理后的分支合并回公共分支。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM