wfxr / forgit

:zzz: A utility tool powered by fzf for using git interactively.
MIT License
4.32k stars 136 forks source link

GCP Doesn't order the commits in oldest to newest, which can lead to merge errors #253

Closed cjappl closed 1 year ago

cjappl commented 1 year ago

After doing a very messy cherry-pick the other day, I noticed that forgit just passes in the selections in order they were selected.

This means if you have a commit history like this, that you are cherry picking from

my_target_branch

commitA
commitB
commitC

and you used gcp to select all of them in the order B, C, A - it would be fed to git cherry-pick in the order B, C, A.

I think we should re-order the list in topo order, such that no matter what the order they were selected in, they would be fed in to git cherry-pick like: git cherry-pick commitC commitB commitA

This would prevent many merge conflicts - in general folks probably want to cherry pick in order from oldest to newest.

I attempted for a while to get this to work, but to no avail. Anyone have any thoughts?

Some discoveries I've made that may be helpful:

List the commits from the $target in topo order:

git rev-list --topo-order --no-walk --abbrev-commit --branches $target

we have all of the abbreviated commits in an variable called commits

echo ${commits[@]}

We could possibly iterate over the commit in commits, try and match them to the rev-list and put them in a new array?

I'm missing the tools to complete this. Interested in your thoughts @wfxr and @carlfriedrich

carlfriedrich commented 1 year ago

@cjappl I already noticed this as well, and I agree with you that the current behavior is not optimal. fzf unfortunately does not supply a way to keep the order of the input. There is a fzf issue, though, where the author suggests a way to keep git commits sorted in their historical order by adding line numbers to the input and then sorting the fzf output by those:

git log --oneline --color=always | nl | fzf --multi --ansi --with-nth 2.. | sort -nk1

That actually works for me. We would have to remove the line numbers afterwards from the output, though:

git log --oneline --color=always | nl | fzf --multi --ansi --with-nth 2.. | sort -nk1 | cut -f2-

Does this command chain work on MacOS as well?

cjappl commented 1 year ago

Works like a charm @carlfriedrich ! That's exactly the behavior I wanted. Let me see if I can turn this into a commit

cjappl commented 1 year ago

I think this functionality could be used in grc as well, where the reverts should be applied preferably from newest to oldest to have the highest chance of working properly the first go around

carlfriedrich commented 1 year ago

@cjappl That sounds useful.