2

I have a set of commits, in reverse git log order, in the same flat branch:

2018-01-01 AAAA1 "Some work 1"  # Changes on directory
2018-06-01 SOME_OTHER_COMMIT "Unrelated commit in order"
2019-01-02 BBBB1 "Some work 2"  # Changes on directory
.....
2018-01-01 AAAA2 "Some work 1"  # Changes on file
2019-01-02 BBBB2 "Some work 2"  # Changes on file

This is the result of moving some code with history from another repo. Directory moved out with git subtree split while single file via git -am, patch. Though it is unrelated to the original question while explaining the repository state

Now, I scripted the iteration of related commits. Grouping them by commit time.

E.g.,

for_each matching_commit_hash_pair
    Rebase and squash "2018-01-01 AAAA1" + "2018-01-01 AAAA2" => "2018-01-01 AAAA-some-other-hash"

The question is, how this final non-interactive rebase (if rebase it is) would look like?

git rebase --onto AAAA1 ... just_single_AAAA2 commit <same_common_message>

Which is literally, moving sole AAAA2 commit to the past, right after AAAA1, keeping everything else the same

AAAA1
AAAA2
SOME_OTHER_COMMIT
BBBB1
BBBB2

With a final squash:

AAAA_SQUASHED
SOME_OTHER_COMMIT
BBBB_SQUASHED

While I didn't check the final squash of sequential-to-be commits, I'd expect it to be easy, same one-liner maybe

Vetal
  • 275
  • 1
  • 3
  • 13
  • 1
    Can you not simply use `git rebase -i`, bring the commits in the right order and change `pick` to `squash` or `fixup`? – mkrieger1 Apr 20 '23 at 10:04
  • Not sure how can I embed it into the iteration script Though the structure is flat number of these commits-to-join is huge. So, it is a big loop of commit hash pairs. And any interactive rebase is not an option. Where the commit message is clear and no commit conflicts hence objects have originally been together – Vetal Apr 20 '23 at 10:07
  • 1
    And if you use `git cherry-pick`? (pseudocode: `foreach hash in commits-in-right-order: git cherry-pick hash`) – mkrieger1 Apr 20 '23 at 10:10
  • And ... delete picked commit by hash right after the cherry-pick injection? If I understood it right, it should work – Vetal Apr 20 '23 at 10:11
  • You can pass a custom todo-editor to `git rebase -i`. It does not have to be a "real" editor, it could also be a script. – knittl Apr 20 '23 at 11:23
  • Why doesn’t git-rebase(1) have a `--batch` option that makes the non-interactive “interactive” mode more apparent? Wondering out loud. – Guildenstern Apr 20 '23 at 13:10
  • Related question here: [Is there a way to split a commit into fixups for the different commits it affects?](https://stackoverflow.com/q/75389020/184546) – TTT Apr 20 '23 at 20:55
  • If you're willing to rerun "Now, I scripted the iteration of related commits. Grouping them by commit time." you could change the second commit message to be: "fixup! ". Once you have all of those fixup commits done you can simply do `git rebase --autosquash -i` (Then save and exit. If you want to avoid the prompt, see the linked related question for an example.) – TTT Apr 20 '23 at 21:05

1 Answers1

0

Ended up solving issues another way around, splitting folder and file together to another repository. Duplicated commits squash are not needed this way

There are a bunch of questions and answers on how to do it, but neither is to fix my issue directly.

So, I am splitting dir1/dir2 and dir3/another-file.ext with history. <=== this part is not included into SO answers

Here is my final snippet:

src_repo="source-repo-path" &&\
dst_repo="new-repo-path" &&\
branch="split-repo" &&\
cd "${src_repo}" &&\
git branch "${branch}" && git checkout "${branch}" &&\
git filter-branch -f --index-filter 'git rm --cached -qr --ignore-unmatch -- . && git reset -q $GIT_COMMIT -- dir1/dir2 dir3/another-file.ext' --prune-empty -- --all &&\
mkdir --parents "${dst_repo}" && cd "${dst_repo}" &&\
git clone --single-branch --branch "${branch}" "${src_repo}" . &&\
git remote rm origin

Source repository cleanup with files removed, filtered branch removal and pushing new repository are not included in the snippet

Vetal
  • 275
  • 1
  • 3
  • 13