8 ms·
FWIW, I've been using this alias for the past couple years for fixup commits, and I've been happy with it: > gfx='git commit --fixup $(git log $(git merge-base
by AndrewHampton 2y ago
FWIW, I've been using this alias for the past couple years for fixup commits, and I've been happy with it:
> gfx='git commit --fixup $(git log $(git merge-base main HEAD)..HEAD --oneline| fzf| cut -d" " -f1)'
It shows you the commits on the current branch and lets you select one via fzf. It then creates the fixup commit based on the commit you selected.
- nickspain 2y agoNice! I use git revise[^1] a lot which does a similar thing but without the fixup commit. I I’ll try using fzf to make it interactive though. Thanks! [^1]: https://github.com/mystor/git-revise https://github.com/mystor/git-revise
- kccqzy 2y agoIf it only lets you select one, that's strictly less powerful. What if I want some parts of it into one commit and another parts into another? The `hg absorb` works for this case.
- kadoban 2y agoThat sounds like what `git add -p` is for, stage part of the current changes.
- k3vinw 2y agoMight be able to use the multimode flag in the fzf command above and it should let you select more than one using Tab and Shift+Tab.
- atq2119 2y agoThen you use `git gui`, which is part of the git distribution itself, or `tig` if TUIs are your thing. I have a key binding for `git commit --squash=%(commit)` in my tig config, so I can interactively select lines or hunks to stage and then the target commit for the squash.
- AndrewHampton 2y agoYeah, it's definitely less powerful that what absorb is doing. I wasn't trying to argue that it was equivalent. I just wanted to share a bash one-liner that I've had success with in case others find it helpful. > What if I want some parts of it into one commit and another parts into another? Looks like absorb will automatically break out every hunk into a separate fixup commit. My one-liner will create 1 fixup commit for everything that's staged. That's typically what I need, but on the occasions it's not, I use `git add -p`, as kadoban mentioned, to stage exactly what I want for each commit.
- mst 2y agoOh, hrm, looking at this description and the one liner, I rather like. Once you mentioned `git add -p` I realised that this is pretty much what I do already, except with a far more efficient way of selecting the relevant commit to do it to. Muchas gracias.
- AndrewHampton 2y agoYeah, I use about a dozen git aliases in my normal workflow. In case it's helpful, here are the relevant ones for this flow: alias git_main_branch='git rev-parse --abbrev-ref origin/HEAD | cut -d/ -f2' alias gapa='git add --patch' alias grbm='git rebase -i --autosquash $(git_main_branch)' alias gfx='git commit --fixup $(git log $(git_main_branch)..HEAD --oneline| fzf| cut -d" " -f1)' Another favorite is: alias gmru="git for-each-ref --sort=-committerdate --count=50 refs/heads/ --format='%(HEAD) %(refname:short) | %(committerdate:relative) | %(contents:subject)'| fzf | sed -e 's/^[^[[:alnum:]]]*[[:space:]]*//' | cut -d' ' -f1| xargs -I _ git checkout _" gmru (git most recently used) will show you the branches you've been working on recently and let you use fzf to select one to check out.
- account42 2y agoCouldn't you just use --patch with the alias to achieve that?
- mckn1ght 2y agosounds like how magit lets you create fixup commits in emacs
- masklinn 2y agoWorse in fact, since magit lets you fixup, squash, or instafix.
- AndrewHampton 2y agoThis was 100% my inspiration. I used emacs+magit for years. After switching away from emacs for dev work, I still cracked it open for git interactions for another year or so. Eventually, I moved entirely to the shell with a bunch of aliases to replicate my magit workflow.
- dangitman 2y ago[dead]
- johnnypangs 2y agoI’ve been using this: alias gfixup="git commit -v --fixup HEAD && GIT_SEQUENCE_EDITOR=touch git rebase -i --stat --autosquash --autostash HEAD~2" From what I understand it does the same thing as this crate for the most part. All I do after is: git push —force-with-lease Not sure what you get from the crate otherwise
- johnnypangs 2y agoI guess the crate version is easier to soft reset?
- masklinn 2y agoYour alias seems like a completely unecessary complexity. If you want to meld new changes into your branch head you can just alias “git commit --amend”, you don’t need that mess. Absorb will find the commits to fix up for each change in the working copy, it doesn’t just merge everything into the head.
- johnnypangs 2y agoI see, the reason it’s that long complicated alias was that I didn’t want to open up the editor to change the commit every time I updated. “git commit —amend” does that. I read the rough how it works and it now makes sense. I might give it a try. Thanks!
- johnnypangs 2y agoSeems like you can add —no-edit and get the same behavior, now I can delete that alias. Thanks again :) (Edit: typo)
- masklinn 2y agoThat is correct, and there is a `--edit` to revert that, so my personal alias is to `git ci --amend --no-edit` such that by default it just merges the staging into the HEAD, and then tacking on `-e` will open the commit message in an editor to expand it.
- psadauskas 2y agoI have this one in mine: https://github.com/paul/dotfiles/blob/master/git/.gitconfig#L59-L60 https://github.com/paul/dotfiles/blob/master/git/.gitconfig#... # make a fixup commit for the last time the file was modified cff = "!f() { [ -n $@ ] && git add $@ && git commit --fixup $(git last-sha $@); }; f" # Get latest sha for file(s) last-sha = log -n1 --pretty=format:%h --grep 'fixup!' --invert-grep Given a file like `git cff path/to/file.rb`, It'll find the last commit that touched that file, and make a fixup commit for it. Its great for the try-this-change-on-CI cycle: Change the Dockerfile, git cff Dockerfile, push, repeat, without it screwing up because you changed a different file while you were working on it.
- mdaniel 2y agoIt won't matter until it does, but $@ expands arguments into separate words but those expansions are themselves only word-preserved if the $@ is itself quoted. The [ will probably get away with what you want, but its use in $(git add) and $(git last-sha) almost certainly will not $ cat > tmp.sh <<'FOO' for a in $@; do echo "a=$a"; done echo for b in "$@"; do echo "b=$b"; done echo for c in $*; do echo "c=$c"; done echo for d in "$*"; do echo "d=$d"; done echo FOO $ bash tmp.sh 'alpha beta' $'charlie\ndelta' a=alpha a=beta a=charlie a=delta b=alpha beta b=charlie delta c=alpha c=beta c=charlie c=delta d=alpha beta charlie delta
- psadauskas 2y agoYeah, you're probably right. I guess I haven't run it on any files with spaces in the 6 years since I added it to my dotfiles.
- emersion 2y agoWith a shell such as fish, one can "git commit --fixup <tab>" and a list of commits will be displayed.
- jonS90 2y agoFunny that I've been doing something nearly identical, but with way more boilerplate. fzfCommit() { local FZF_PROMPT="${FZF_PROMPT:=Commit: }" git log --oneline | fzf --border --prompt="$FZF_PROMPT" --height=10 --preview="git show {+1} --color=always" --no-sort --reverse | cut -d' ' -f1 | tr '\n' ' ' | sed 's/[[:space:]]$//'; } function gfixup { local commit=$(FZF_PROMPT='Fixup Commit: ' fzfCommit) if [[ -z "$commit" ]]; then return 1 fi set -x git commit --fixup "$commit" --allow-empty > /dev/null || return 1 git rebase --interactive "$commit"~ --autosquash || return 1 }
- deleted 2y ago[deleted]