0

Say I'm working on a project with two tickets. And has some dirty commits.

commit4 do ticket2.2
commit3 do ticket1.2
commit2 do ticket2.1
commit1 do ticket1.1

Is it safe, if I reorder it to such like this with no conflict:

commit4 do ticket2.2
commit3 do ticket2.1
commit2 do ticket1.2
commit1 do ticket1.1

I think git judge conflict using what deletes and what adds(Sometimes not very clever however). But if we reorder commits with no conflict, is it guaranteed to be the same code with previous? And how can we prove that?

I've been quite frequently using git rebase -i to reorder commits and checked git diff later, the code was same as expexted. But is it always true?

2 Answers2

1

No, it's not guaranteed to be the same code because there is a conflict, the final code cannot be determined, or (somewhat of a stretch) includes the conflicted patch!

However, what you're doing is rebasing the commits and may indeed be what you want to do (git rebase)

Finally, the conflict may be quite important (or trivial), and you should review it before blindly rebasing over it to ensure the result is what you want and expect (otherwise you can go further and evilly clobber any merges with your side git merge -s recursive -X ours vs git merge -s ours? .. which is also likely to give quite different and very undesirable results)


If there's no conflict (or you resolved the conflict), you can compare the before and after state with git diff

git checkout branchA             # commits in order A
git diff HEAD~4.. > testA.patch  # save output
git checkout branchB             # commits in order B
git diff HEAD~4.. > testB.patch
diff testA.patch testB.patch     # ideally no differences here

Here, ~4 is the -4th commit, inclusive, so if you added a merge commit, you might have ~5 .. it may also be easier to name the commits aaaaaaa..fffffff, but that will of course vary by-use


Finally, there's some difference between always being certain and the common case of plain text (code) files

With the former "always" / "in every case", it's likely you will find ugly edges around the addition of something like .gitattributes or .gitignore, which when reflowed could make all sorts of exciting changes, like changing a filter rule or no longer including it!

While with the latter (and likely more common) case of plain text files, simply diff is sufficient (though you should still be observant of special attributes)

ti7
  • 16,375
  • 6
  • 40
  • 68
  • Thx. If has conflict it is, but what if no conflict? – Shayens Will Nov 21 '22 at 06:45
  • there's some practicality for if you're considering exact commits (ie. for `cherry-pick`ing), or their content (each commit is a patch you `apply`), but the code result will be the same if no conflict is generated and more practically, if they don't change the same lines - do note, however, that `rebase` will change the commits so that they are patches against the new base (while potentially fixing a conflict) – ti7 Nov 21 '22 at 11:38
0

u need to understand how git rebase -i work,

it 's simply just "recommiting" patches in different order one by one.

if there was any conflict during one of the commits , git would interrupt the rebase operation, and ask u to resolve the conflict, after that u continue for the next commit.

in conclution

If git doesn't interrupt your rebase operation, it means that there is no conflict at all. don't worry~

Peter
  • 29
  • 2
  • I'm not really undertstand the conflict stragety git using, sometimes add a new line could cause a conflict. Or git trend to be conservative? If that, "Reorder without conflict." can be safe. – Shayens Will Nov 22 '22 at 06:17
  • @ShayensWill For example, there is no back-and-forth dependency between the four submissions (for example, the location of the modification happens to be different), so no matter how you change the order or how many lines you change, there will be no conflict at all. What I want to say is that if there is a conflict, git rebase -i will prompt you immediately, and you will continue to rebase after you resolve the conflict. "-i" refers to "interactive" – Peter Nov 22 '22 at 07:05
  • In addition, if you want to understand the conflict mechanism of git, git config --global merge.conflictstyle diff3. Then create a conflict, how to create a conflict is very simple, pay attention to the modification of the current HEAD node (assuming the hash is 123456), such as modifying the a file line b, then you roll back to HEAD^ (that is, the parent node of HEAD), modify line b of file a (but the modified content is different from HEAD), create a commit, and then you are now git merge 123456, there will be a conflict – Peter Nov 22 '22 at 07:16