If you imagine a VCS where merges didn't exist, then what would you do when the code is updated after you started on a change you were making? You probably would get a copy of the most up to date version of the code and try to apply your changes to it and make sure it still works.
That's essentially what rebasing does.
What merges do is basically try to have the VCS apply the code changes you made based off an older version of the code and apply it to the newer version of the code. Conflicts are changes you made to your code or the base code in order to get your code to work.
So, it really comes down to the following:
1. Would a reviewer want to view the changes based on the most up to date version of the code as a set of one or more changes?
or
2. Do they want what's in item 1 and then one or more commits that are autogenerated with a mix of automatically applied changes as determined by the VCS and manual changes that are a mix of changes to the base code and code that's part of the new feature?
I assert that it's easier to deal with option 1 because we can clearly see, in a set of organized commits, what changes were made based on the latest version of the code. With option 2, you mix what's in option 1 with automatically generated commits mixed in with changes that update lines of code that may have been made by multiple commits previously applied to the branch.
> a junior developer attempted a rebase or amended a commit in a branch they shouldn't have.
Developers, in general, should look at the commits in their branch by running:
git log -p origin/master..
and read through the commit messages and diffs and see if things make sense. They can also test each change by running:
git rebase --exec "test_command" origin/master..
in order to verify that the changes introduced by each commit didn't break any of the tests.
I've certainly used VCSes where merges didn't exist as a first class citizen. They are a huge pain to use, still have to deal with merges and merge conflicts somehow, even if they just push all that work onto the user.
Git presents a DAG as a data structure. Forcing it into a "straight line", in my opinion, is a silly amount of work when you can use the power of a DAG, including filtering/culling your "depth" views into the DAG to manage it.
I understand that a straight line is "cleaner" and often easier to read. I'd rather use the power of the DAG to query straight lines than do a lot of work up front to artificially make straight lines. I understand that this is a difference of opinion you are unlikely to share, that's fine, there's no "one workflow" for everyone.
Even if you filter out the merge commits, then you're hiding some of the changes made when you look at the history of the branch. The other problem is that if you run git blame on a file and the line is referenced by one of those merge commits, then the commit message is next to useless. Those looking at the history want to know why that line is there (changed from a previous version or added). A commit message that explains the reason and allows you to see that line in a context of a logical change makes it much easier to determine whether the change you're planning to make will introduce a regression or lead to some other issue. A merge commit message with a mixture of changes that may pertain to any number of commits in the branch doesn't help and makes it harder to figure out what the change was.
That's essentially what rebasing does.
What merges do is basically try to have the VCS apply the code changes you made based off an older version of the code and apply it to the newer version of the code. Conflicts are changes you made to your code or the base code in order to get your code to work.
So, it really comes down to the following:
1. Would a reviewer want to view the changes based on the most up to date version of the code as a set of one or more changes?
or
2. Do they want what's in item 1 and then one or more commits that are autogenerated with a mix of automatically applied changes as determined by the VCS and manual changes that are a mix of changes to the base code and code that's part of the new feature?
I assert that it's easier to deal with option 1 because we can clearly see, in a set of organized commits, what changes were made based on the latest version of the code. With option 2, you mix what's in option 1 with automatically generated commits mixed in with changes that update lines of code that may have been made by multiple commits previously applied to the branch.
> a junior developer attempted a rebase or amended a commit in a branch they shouldn't have.
Developers, in general, should look at the commits in their branch by running:
and read through the commit messages and diffs and see if things make sense. They can also test each change by running: in order to verify that the changes introduced by each commit didn't break any of the tests.