35 comments

[ 6.2 ms ] story [ 80.1 ms ] thread
Four rules for how to effectively collaborate with me and people that agree with me.

One rule for how to effectively collaborate - talk to the people you are trying to collaborate with about expectations and then follow them. Try to remember along the way that you are all human.

You're correct. There are more fundamental conditions that have to be met for effective collaboration.
On the other hand, using this as a baseline and evolve from there will save a lot of time. I mean git conventions are starting to sound a bit like tabs vs spaces, just with a lot more options.

Pick a standard example, go with that, evolve. Same with e.g. processes, pick e.g. scrum, do it by the book at first, evolve.

I've started at half a dozen projects and every time a huge amount of time is being spent (wasted) on reinventing the wheel, be it processes, version control, code style, etc.

This should be retitled: Reasons Why The CL is Flawed.

Long to short, why can't this be a form of some sort? Engineers / developers have enough to worry about, why add more minutia to the pile?

The CL is not an adequate OSFA solution. If quality and quantity is a concern, when is that going to be addressed?

I don't understand what a form has to do with CL tools and their weaknesses. If you think that a form would help create better commits and commit messages, you can set one up in the CL. You can think of all of Git's interactive options as forms or wizards.

There is also pulling commit messages from a file. The commit -F /path/to/file switch allows you to specify a file that Git will pull text from. I try to write my commit messages before I make a change, because it helps me ensure that everything I'm working on satisfies the single-thing-per-commit rule. I always update the same file, so I made it an alias:

    git config --global alias.commit-txt 'commit -F ~/commit.txt'
Edit: If you're unfamiliar with how aliases work, you create one with the above invocation. The portion after alias. is the command you define and want to type. The portion in single-quotes is the actual git command. Thus, you'd type

    $ git commit-txt
to use the above command. What the command line sees is

    $ git commit -F ~/commit.txt
A form would allow a team to define what gets entered, just like a checkout form defines a sellers needs. As it is, it's left up to human memory. That's flawed. I thought we knew and agreed on this.
> Long to short, why can't this be a form of some sort? Engineers / developers have enough to worry about, why add more minutia to the pile?

It can! See Commitizen and its cli, used by e.g. the Angular project, which offers a cli wizard for filling in a commit message - type (fix, feature, chore, ci, doc, etc), scope (depends on project, one word category), short description, backwards-incompatble changes, etc; see http://commitizen.github.io/cz-cli/. This system can then be used to generate changelogs and do semantic versioning compatible version bumps - patch releases if the diff since the last tag only contains 'fix', minor if it contains 'feat', major if it contains backwards incompatible changes.

So you say to me rule 2 for effective collaboration is answering those 5 questions :

Why is this change necessary? What assumptions is it based on? Were any alternative solutions considered? Why was this solution chosen from among the alternatives? Are there any non-obvious implications that this change has?

But none of the proposed rules actually answer those 5 questions in their explanation.

Also then you get people writing their life time stories in commit messages instead of writing code, good luck with velocity.
Thinking that providing additional context for commits is a waste of time is short-sighted. Yes, it requires more time and effort in the short-term (i.e. for creating the commit), but if it's a complex, long-lived project, then that extra effort will save a lot of time in the long run.

Sometimes the extra time and effort is already made up for in the review process, which without proper context could drag out and cause a lot of back and forth. Sometimes it might save somebody hours and days of investigation time. This is not to mention the benefits that both the author and the readers of the commit get by better understanding both the problem and the solution.

People are bad at finding out what is important and what is not. Most of the time I have to cut through not relevant stuff that others thought would be important for fixing some issue. Lot more than some insightful commit saved my day, but maybe that is just my environment.

Anyway good luck fixing anything trusting commit messages from long time ago. Code is truth and if you won't investigate you still don't know how it works.

Writing more code that no one understands the reason for is not better than writing explanations of why you wrote some code.
Then why not focus on writing readable code? And when you do need to write a workaround or something hard to understand, then document it in the code itself with a comment. It'll be recorded in the diff of the commit, plus it'll be more accessible when reading the codebase as a whole.
These aren't mutually exclusive things. Write readable code so people can see how you did it. Write complete commit messages so that people understand why you did it. Especially with older codebase, hairier things you inherit that are full of monsters and WTFs, you need both.

It's more work for you, but it saves the rest of the team even more time. It helps the dev reading it in three years understand, when he git blames to figure out why you did this strange thing.

Three to four of these should be captured in your ticketing system. Only why should go in the commit, along with the story number.

If you have never used tools that can automatically link commit messages to stories you are truly missing out.

It's a bit baffling that git.git suggests using 7-characters commit abbreviations, when they already have collisions for them:

  $ git log --oneline | cut -c 1-7 | sort | uniq -c | grep -v ' 1 '
        2 1536dd9
        2 191f241
        2 2e6e3e8
        2 3b130ad
        2 d53a350
7 characters should be enough for most repos, and iirc git can deal with collisions already (so git co 1536dd9 in your example would bring a prompt).

How many commits is the repo you're running this on btw?

Sure. And randomly generated UUIDs should not conflict... unless they do, and blow up a huge app in production. Yes, I have experienced that once.
Where did you find the 7 character suggestion? 7 used to be the default suggestion, but the problem of collisions has been acknowledged and dealt with by the git project. Linus himself authored the change that made the abbreviated revision length vary based on the size of the repository: https://github.com/git/git/commit/e6c587c733b4634030b353f402.... Also, the command for creating references to other commits which comes from the git project and is linked to in the article also uses automatic abbreviation length.
Maybe get your ticketing system tied to repo and add reference ticket number form a system where whole context can be provided in a proper way.

"Every commit should be complete." and "Every commit should only do a single thing." and then make it in a way that someone could actually review changes. In most cases it is not possible, more often it is complete or does single thing.

Tying the ticketing system and the repository together is a good idea and definitely worth implementing, but there's a fine balance in deciding what context should be kept in the ticket and what in the code repository. If you put too much into to the ticket and too little into the commits, then git blame loses it's value, for example.
Yes just be reasonable, whatever it means in context of change/team/project.
In my experience these assertions are untrue. Also the tickets are often the over arching context and will have nothing to do with the code. My product owner doesn't care if I had to try three different algorithms till I got it right; but my colleagues and my future self sure would love to see that and all the stack overflow links during a git bisect!

Not only that but the ticket is a full feature. Maybe it took 5 commits to get there: "Fix bad indenting", "Extract base logic to command object", "Update I18N entries", "Add missing tests for current behavior", "Add the feature asked for".

From what I see you just agree with my comment. Those 5 commits you described as example are the way I would do it.

The way it is described in article would make you do it in one commit and add information that would be in the ticket.

What makes you say that? The Focused rule from the article is also meant to persuade you to split the work into similarly concise and focused commits.
Focused and complete are opposite. You can have focused commits or complete commits.
Also, the ticket and the commits can provide answers to the same questions without being redundant. The answers are just at a different level of abstraction and for different readers. Tickets usually describe product-level decisions, while commits describe implementation-specific details. E.g. a ticket may discuss alternative user flows, while a related commit explains why a specific algorithm, module, or default configuration value was used.
I used to work with people who didn't comment their commits at all. The company went belly up
All of these are prescriptions for establishing a narrative for your commits.

First you must convince people that the obviousness of their commits decays rapidly. What was obvious ten commits ago will be completely opaque three hundred commits from now.

Then you must convince them that the descriptions of the commits are often instrumental in fixing bugs without introducing regressions.

And to do both of these you must convince them that this code will survive for a long time. Everyone behaves like they won’t be here for the consequences or like they can “fix it later”. One of those tomorrows never comes.