Remember that the more you treat commit history as something to be read, the better these tools get. If you’re just jamming “-m” on `git commit` with nonsense like “fix bug”, “pr comments”, “ci”, then you’re going to have a bad time debugging with Git. Also, if you have mandatory squash and merge, congrats, you’re destroying history all the time that can help you debug things.
Ours isn’t much better.
Each commit message has a mandatory ticket number you have to enter.
So for details you need to jump to the ticket.
The tickets often don’t have meaningful information in them apart from ‚for details see the attachments‘
Attachments are often either not uploaded or nowadays we do not have read access as they were created by a different team working for a different customer but forwarded to the ‚central backend team’ and for know how protection purposes we are not even allowed to see the attachments.
Effectively resulting in the information that is available telling us: ‚we did stuff‘
That's one alternative. Another alternative is cleaning that up in a rebase into a series of (hopefully) easy to follow individual commits that do one thing, and then a merge commit pulling in the branch with a description of the change as a whole (and a reference to the pr and any relevant tickets). There are other alternatives as well that make various tradeoffs between effort for the author, effort for the reviewer, ease of reading the git history, applicability of various tools, etc.
Why would you write such commit messages instead of describing what changed and, if needed, why?
I find it quite rude to change a codebase and not leave an explanation in the version control metadata. Over the lifetime of the application that's the source of truth. You can type in whatever in Jira or Trello, what's in version control will be built and shipped anyway, and they're unreliable. Sooner or later someone will think it's a good idea to 'clean up' and delete stuff, or someone decides to migrate to another project management supplier and issue-tags in commit messages become dead links.
The point of squash is that the "history" is nonsense like "fix" etc. There are two types of commit: versions and checkpoints. The latter are just to help you develop and can include stuff like "end of day" that should never end up on master. Squashing is a way to turn those into versions. Blindly squashing every branch down into one commit is stupid, though.
> The point of squash is that the "history" is nonsense like "fix" etc. […]
Using squash when appropriate is good. But then it should be generalized to “rebase” since that doesn’t ever imply a certain strategy like “squash everything”.
> Blindly squashing every branch down into one commit is stupid, though.
Yep, which is what OP is complaining about (mandatory squash).
I usually keep all my work in a stash until I'm ready to create the PR. I used to preface my intermediate commits with "WIP -" and then reset the branch and re-commit everything when I was ready to create the PR, but that was just too much effort
Meh, you can easily twist that into a bad policy, too (and yes, people do that). At work, some of my colleagues litter many repos (I don't usually have to work with, thankfully) with dozens of commits having the same ticket ID and the title of the ticket as their subject. Usually pushed straight to trunk (full of foxtrot merges if two people work at the same time). And in the message body, then, there's usually the unhelpful "fix typo".
My opinion: Write readable messages, scope your commits to simple changes, put them on a branch, use `--autosquash`, put the ticket ID in the merge commit's message. It really isn't hard.
git blame shows only who made the last change. Maybe that person only changed the name of a variable, applied a codestyle change, moved a function declaration to another file or many other things that the change was almost irrelevant to the code behavior.
There are a few options that help you out with this:
-M Detect moved or copied lines within a file
-C In addition to -M, detect lines moved or copied from other files that were modified in the same commit.
--ignore-rev <rev> Ignore changes made by the revision when assigning blame, as if the change never happened
--ignore-revs-file <file> Ignore revisions listed in file
I wish they would make long option names for everything, including -C and -M. (Perhaps I should contribute that..)
I use short options interactively on the command line, but in scripts and when communicating with other people, I prefer longer options because they are self-documenting and can catch most typos. (For a long option, typos are more likely to result in an invalid option, and thus an error message. For one-letter options, a typo could result in anything..)
I recommend just skipping blame and going to git log -L to see the full evolution of a range of lines, I set up a little keybind in vim which does this for the current visual selection and it works much better than blame.
These are the things that can be a chore to find in man pages. There needs to be a way to "sort" man page elements to show most commonly used switches first.
I recently found out that git rebase has a --exec option that allows you to execute a shell command for each commit. If the command fails, the rebase pauses and allows you to make changes to make the command pass. I use this to make sure that there is no commit that leaves my project in an unbuildable state.
Another thing you can do when you have two versions, one which fails and one which doesn't, but where the commits are of the messy work in progress nature and not atomic changes, is gradually stage the changes from the bad version onto the good version until it starts failing
That's a smart way to do it. When I was in this situation without having thought of that, I ended up chunking the monster commit into as small changes as possible with `git add -p`, and then used git rebase as my bisect (since I didn't know how bisect worked either) by rewinding through time until i had found the micro-commit that contained the error.
Didn't know Git had a bisect feature. I'll keep that in mind for later.
Other than bisect though, I do think a lot of the practices outlined in the article (checking the blame, logs, search, etc) is way easier to do in a web UI, at least for someone like me who hasn't tailored their workflow for the command line. The tooling is so ubiquitous that it's easily available. I personally think GitHub does okay in those regards.
Personally, I've tried some graphical tools (e.g. magit on Emacs and the git tools on JetBrains IDEs), but still prefer CLI as I think those UIs hide too much from the user, specially in more complex repositories (e.g. repos with submodules).
These features (except blame) are more advanced features, that may be hidden in those interfaces. Instead of remember where they are behind some menus or shortcuts, I prefer to remember their CLI as it is faster.
Git Bisect has saved me multiple times. It's such a simple concept, but being able to hone into the commit where something is broken is almost always useful.
I've never tried automating it. That'll be fun to try next time I'm in trouble.
> Also, if you have mandatory squash and merge, congrats, you’re destroying history all the time that can help you debug things.
Well the alternative is 100s of commits like this:
fix bug
added file
fix typo
fix typo
update test
test
test
test
fix typo
added file
The tickets often don’t have meaningful information in them apart from ‚for details see the attachments‘
Attachments are often either not uploaded or nowadays we do not have read access as they were created by a different team working for a different customer but forwarded to the ‚central backend team’ and for know how protection purposes we are not even allowed to see the attachments.
Effectively resulting in the information that is available telling us: ‚we did stuff‘
I find it quite rude to change a codebase and not leave an explanation in the version control metadata. Over the lifetime of the application that's the source of truth. You can type in whatever in Jira or Trello, what's in version control will be built and shipped anyway, and they're unreliable. Sooner or later someone will think it's a good idea to 'clean up' and delete stuff, or someone decides to migrate to another project management supplier and issue-tags in commit messages become dead links.
Using squash when appropriate is good. But then it should be generalized to “rebase” since that doesn’t ever imply a certain strategy like “squash everything”.
> Blindly squashing every branch down into one commit is stupid, though.
Yep, which is what OP is complaining about (mandatory squash).
Deleted Comment
You can also use it to split and individually pick changes if you want to clean up your commits.
You can automatically fix up commits after review commits using git absorb [1].
[1] https://github.com/tummychow/git-absorb
My opinion: Write readable messages, scope your commits to simple changes, put them on a branch, use `--autosquash`, put the ticket ID in the merge commit's message. It really isn't hard.
There are a few options that help you out with this:
-M Detect moved or copied lines within a file
-C In addition to -M, detect lines moved or copied from other files that were modified in the same commit.
--ignore-rev <rev> Ignore changes made by the revision when assigning blame, as if the change never happened
--ignore-revs-file <file> Ignore revisions listed in file
https://git-scm.com/docs/git-blame
I use short options interactively on the command line, but in scripts and when communicating with other people, I prefer longer options because they are self-documenting and can catch most typos. (For a long option, typos are more likely to result in an invalid option, and thus an error message. For one-letter options, a typo could result in anything..)
https://magit.vc/manual/magit/Commands-for-Buffers-Visiting-...
Deleted Comment
Basically git checkout -p until things fail
Other than bisect though, I do think a lot of the practices outlined in the article (checking the blame, logs, search, etc) is way easier to do in a web UI, at least for someone like me who hasn't tailored their workflow for the command line. The tooling is so ubiquitous that it's easily available. I personally think GitHub does okay in those regards.
These features (except blame) are more advanced features, that may be hidden in those interfaces. Instead of remember where they are behind some menus or shortcuts, I prefer to remember their CLI as it is faster.
I've never tried automating it. That'll be fun to try next time I'm in trouble.
Deleted Comment
Deleted Comment