8 ms·
Git as a debugging tool
- n4r9 3y agoAnother way to use git to debug - albeit more tedious - is to manually check out branches (using a binary search) until you find the exact change that caused an issue. This is helpful if you have no idea what part of the code is causing a problem, but you know the problem didn't exist a month ago. Performance issues are a good example.
- yjftsjthsd-h 3y agoI don't know about branches, but if you're just traversing history that's a textbook use for git bisect, right?
- globular-toast 3y agoYep. Git bisect automatically does a binary search to find the earliest breaking commit. You can either test each version manually or, if you have a script that will pass or fail, like a unit test, you can tell git and it will do everything automatically. I love it when I get to use git bisect.
- amboar 3y agoA handy trick I've developed is using`git bisect` to solve otherwise intractable rebase conflicts: https://codeconstruct.com.au/docs/bisect-intractable-rebase-conflicts/ https://codeconstruct.com.au/docs/bisect-intractable-rebase-...
- eru 3y agoYou might want to combine this with enabling rerere.
- amboar 3y agoYeah, I have rerere turned on However, it's not directly beneficial for the process outlined. With what I wrote about you only solve a given conflict at the end of a complete bisect run, not at each bisection point inside a run. The bisect/cherry-pick process is only used to determine whether conflicts do or don't happen at a given upstream commit. Usually you will solve a specific conflict only once, regardless of whether rerere is enabled.
- n4r9 3y agoYes, failure to rtfa on my part.
- nonethewiser 3y agoThats called git bisect
- shinycode 3y agoIn jetbrain products, you can select any bloc of code and show the git history for this particular bloc. I don’t know exactly which command is behind it but I always thought it would be tedious to do it manually like you described
- lucasoshiro 3y agoProbably they use libgit2 instead of git. But you can use git log -L for that.
- cerved 3y agoAnother 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 Basically git checkout -p until things fail
- lucasoshiro 3y agoThanks for the comment! It looks to be a very useful tip for doing after bisect on repositories where people insist to squash pull requests.
- john-radio 3y agoThat'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.
- deleted 3y ago[deleted]
- ozay 3y agogit 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 https://git-scm.com/docs/git-blame https://git-scm.com/docs/git-blame
- PhilipRoman 3y agoI 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.
- a_e_k 3y agoAnd for those using Magit in Emacs, you can do this by selecting a region of lines and hitting `C-c M-g l`. https://magit.vc/manual/magit/Commands-for-Buffers-Visiting-Files.html#index-C_002dc-M_002dg-l https://magit.vc/manual/magit/Commands-for-Buffers-Visiting-...
- jmholla 3y agoNice. Can you share your vim configuration for that?
- billllll 3y agoDidn'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.
- lucasoshiro 3y agoPersonally, 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.
- izoow 3y agoI 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.
- eru 3y agoYou can also use `--interactive` to do a lot of complicated stuff.
- penguin_booze 3y agoFWIW, you can use `git rebase --edit-todo` in the middle of an interactive rebase, just in case you changed your mind about what comes next.
- deleted 3y ago[deleted]
- tombert 3y agoGit 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.
- penguin_booze 3y agoFWIW, there's `git bisect run` and `git bisect replay`.
- interbased 3y agoI never knew about the -s flag with git log. That would be super helpful in many situations for me / my team.
- deleted 3y ago[deleted]
- teeray 3y agoRemember 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.
- whoitwas 3y agoAgreed. A good policy is to include ticket number and a short description.
- btschaegg 3y agoMeh, 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.
- teeray 3y agoI save that and one or more “Reviewed-by” trailers for the merge commit message (Yes! You can write commit messages there too!)
- MichaelMug 3y agoThis is one of the biggest issues I face at work. I always see "added X", which git can already tell me. > 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
- 3y ago
- yakkomajuri 3y agoDidn't know about all these (especially some flags) so thank you! I've personally used the bisect feature a lot to track down WTF bugs and git blame is essentially embedded into VSCode for me with the git extension, which also helps a ton.
- penguin_booze 3y agoFor interactive blaming from command line, I can recommend `tig blame`: use the `,` binding for blaming the parent that introduced a change, and `<` to "go back".
- jeppester 3y agoThere are two tools I often wonder why so few developers take the time to understand: - git - regex The return on investment is huge. I wouldn't call myself an expert on neither, but just having a good understanding has often felt like a superpower, and made me the one who "fixed the difficult problem".
- penguin_booze 3y agoThis is the only post in my recent memory that talks well of Git. Most others I've seen, gave Git some heat and hatred. To me, Git is like vim: you've to "get it" to love it. I say that as long-time Vimmer and ex-Git hater.
- fernandezpablo 3y ago> A nice way to see the pathspecs in action is using git ls-files. That command lists all the files in the staging area, This should read "That command lists all the files in the _working directory_"
- penguin_booze 3y agoI don't think it's the working directory. AFAIK, ls-files will only list files that are known to Git (i.e., files that have been `git add`). ls-files won't list files that are not known to Git, even if they're present in the working directory.
- digikata 3y agoOn git commands that accept pathspec, other git adjacent tools also accept path spec. e.g. I tend to use gitk or tig with a pathspec when looking at a bug in a particular file or directory.
- penguin_booze 3y agoNot sure why the article left out `git ls-tree -r`: this is as good as doing ls-files at any commit (given as argument), not just at what's currently checked out.
- malingo 3y agogit diff-tree [1] is also super helpful. I've use it a lot to ensure the codebase after a complex rebase is in an identical state as before. [1] https://git-scm.com/docs/git-diff-tree https://git-scm.com/docs/git-diff-tree
- galdosdi 3y agoTIL about `git log -S` (and `git log -G`) from this article (list commits that increased or decreased the number of times a given identifier is found in the source code). Looking forward to needing to use it, that's a nice trick