4 ms·
Not exactly. My goal is mainly that I'd like to avoid running git log and manually deciding the starting commit (and copying its hash around) before rewriting l
by btschaegg 5y ago
Not exactly. My goal is mainly that I'd like to avoid running git log and manually deciding the starting commit (and copying its hash around) before rewriting local branch histories.
What I want to achieve is that I can run my script (i.e. `git autosquash`), and it will automatically start the appropriate interactive rebase for me. That means I still get the rebase description I can check by eye in Vim (and have the option of aborting by emptying the buffer before quitting it).
I usually use this to clean up the history of a private local branch, so I won't trigger anything like `git rebase master`. This means that I have to specify the commit where Git is supposed to start the interactive rebase (i.e. the oldest commit that won't be included). And finding that by looking for the subject line after "fixup!" is rather finnicky (especially if the subject line also matches those of other commits), whereas the simple commit hash would be nice and explicit (and finding the starting point would be a simple `git merge-base --octopus` of all fixup! hashes).
So, my problem isn't the autosquash resolution built into Git, but that I have to reimplement it in a script in order to find the proper rebase starting point. That, and all backward searches for commit messages I know of are either really fuzzy or needlessly convoluted.
The best exact matching search I could come up with is something akin to
git log --pretty=$'%H\x1F%s' "$fixup_commit_hash" | awk -F $'\x1F' -v "subject=$query" '$2 == subject { print $1; exit }'
- avar 5y agoI understand. Is there any reason you don't (or perhaps you're not aware that you can) use the branch upstream info for this? Whenever I work on a branch called "topic" I do the equivalent of "git branch --set-upstream-to origin/master" on it. That means that all of: git log @{u}.. git diff @{u} git diff @{u}... Will use that upstream point (@{u} or @{upstream}). What does this have to do with rebase? If you do: git rebase -i It's the same as doing: git rebase -i @{u} That's probably not exactly what you're asking for, i.e. if you've got a history since master of: A foo B bar C !fixup bar D !fixup bar You'd open an editor with A..D with that, whereas you perhaps only want B..D?
- btschaegg 5y agoYou're right, I didn't know about @{u}, thanks for the hint! > You'd open an editor with A..D with that, whereas you perhaps only want B..D? That wouldn't be much of an issue for me, but I still tried to implement an option that doesn't rely on my repository having a defined remote. I quite often start a new local git repository whenever I'm about to start a new experiment (or just scripting some one-off task), and most of these will never get pushed onto a git server. However, even in those cases, my scatterbrain often triggers the "gah, that should have been in a previous commit!" reflex. By the way: Thank you very much for taking your time and reading all this! :) Edit: I just re-read the upstream-point thing. Wouldn't that cause a `git push` on `thing` to push directly to `origin/master`? That also wouldn't be compatible with the workflow we have at work (we use GitLab merge requests)…
- avar 5y agoYou can set "upstream" to another local branch, no remote is required, it's just how it's typically used. Under the hood it's just a way of naming another reference as a divergence point. I use this extensively with Git(Hub|Lab) (PR|MR)'s. I set the upstream to "master" but push to "topic". The "push.default" docs cover how to have your cake and eat it too there.
- btschaegg 5y agoThe reference to the `push.default` config key clarified a lot of things for me. Thank you very much! :)