Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [ee4j-build] git question



On Thu, 6 Dec 2018 at 18:54, Bill Shannon <bill.shannon@xxxxxxxxxx> wrote:
Tom Jenkinson wrote on 12/6/18 3:38 AM:
As soon as a commit in your tree does not have identical SHA to what is in the main repo it won't push cleanly.
I don't understand.  How are two commits considered to be "the same" if not by their SHA?

If there's a commit in my repo that's not in the remote, and there's a commit in the remote, that's not in my repo, I understand.  But if I do a "pull -r", how can there be a commit in the remote that I don't have?  Doesn't "pull -r" pull down everything from the remote and add my stuff on top of it, without changing what it pulled down?


I tried to simulate it a bit with creating two branches using your current master and then on one of the branches doing a "git commit --amend --no-edit" so although they are both functionally identical both branches have a different SHA for the head commit.
"commit --amend" is effectively the same as completely removing that commit and replacing it with a new commit, right?

I understand how that would get things out of sync, but I wasn't doing that.


git diff test2 (my second branch) - shows no differences

but if I do "git rebase test2" it changes the branch I am on to use the SHA from the test2 branch. History looks clean still but it can't be clean pushed.

If I do "git merge test2" instead, it can be pushed but history does not look nice.

Here are the branches:
My simulation of your master: https://github.com/tomjenkinson/javamail/commits/test (originally exactly like your master - but now the result of running git merge test2)
My simulation of your EE4J_8 branch: https://github.com/tomjenkinson/javamail/commits/test2 (note the SHA is different on the commit "Support building mbox native code on Linux; fix building on JDK 9." - like your commits in EE4J_8 branch have different SHA

There reason they all have different SHA is because the second two commits are in a different order. If master was going to have exactly the same commits in the exact same order you could have done "git rebase EE4J_8" each time and it should have pulled in the lastest commits without changing their SHAs. In practice I don't see how that would have been possible over time as at some point they would diverge.

Whenever I try to sync two branches I cherry-pick commits from the branch that is ahead onto the other branch. That means that history is not re-written on the branch I am cherry-picking to and so I don't need to force push.
So you're saying that rebase might rewrite commits on the main branch, not just add commits from the other branch?  Ouch!

How does it know which commits to rewrite?
From what I know, it will rewrite anything that is different, because you diverged after beab9265aa39a4c3c4a2e220b1e4c198060803a5 then anything after that would be changed.

If you do "git rebase EE4J_8" on master it will be made to look like the EE4J_8 branch where the commits are the same. If you do it twice in a row it won't touch them the next time. That said, if you add more commits to your EE4J_8 branch and rebase master with them you will be back needing to force push because "Support building mbox native code on Linux; fix building on JDK 9" for instance will be re-written and get a new SHA (because it does not occur in the EE4J_8 branch).

If it helps, the parent commit seems to have an influence on the SHA of a commit, a functionally equivalent commit with a different parent gets a different SHA. For example:
At time 1 let the following commits exist in master: 1,2,3,5 (the numbers are SHAs)
At time 1 let the following commits exist in EE4J_8: 1,2,3,4
Then at time 2, say you want to "git rebase EE4J_8 "(on master), master ends up with the following commits: 1,2,3,4,6 (6 used to be 5, but it is not able to be 5 anymore because the SHA of 5 was calculated with a parent of 3, but after the rebase it now has a parent of 4)



On Wed, 5 Dec 2018 at 20:33, Bill Shannon <bill.shannon@xxxxxxxxxx> wrote:
Tom Jenkinson wrote on 12/5/18 10:38 AM:
Hi Bill,

With Javamail repo, when you rebase its master on its EE4J_8 branch some of its commits on master have to be altered by git. These commits are the ones that are either not in the EE4J_8 branch at all and commits where they do not have identical SHAs to those in both branches). These commits get a new SHA and even if only a single commit has a different SHA you can't just "git push" anymore.

You can see the commit histories are different if you look at the bottom 3 commits in https://github.com/eclipse-ee4j/javamail/commits/master and https://github.com/eclipse-ee4j/javamail/commits/EE4J_8. Although the first commit is identical the following two commits are then in a different order and have different SHAs between the two branches.
Ya, that's because someone applied the same changes to both master and EE4J_8 separately.

The same principal can be seen if you do the following:
git reset --hard origin/master
git log -1 # look at the sha
git push
git commit --amend --no-edit
git log -1 # look at the sha now, you will see it is different even if the content of the commit appears identical
git push # this won't work because the commit history is different

This might not have been practical for your case, but generally if the commits had been in master first and then you had been able to rebased the EE4J_8 branch on master (or cherry-picked some commit) you would still have been able to "git push" to EE4J_8 branch because the SHAs would have already been pushed would not need to have been changed (unless you had added commits to EE4J_8 branch that were not on master, then you would be in the same position).

Does that help?
I still must be thinking about rebase wrong...

I think what I had was something like this:

A--B--C   (master)
  \
    D--E--F--G--H  (EE4J_8)

Commits B and E made the same change, and commits C and D made the same change.

When I rebase EE4J_8 on master I expected it to apply commits D and E and realize that they were redundant with commits B and C, and thus they didn't actually change anything, but they would still show up as commits.

I expected to end up with:

A--B--C--D'--E'--F'--G'--H'  (master)
  \
    D--E--F--G--H  (EE4J_8)

It seems like I should be able to push that since it's a superset of what's in the remote master.

Apparently D and E didn't actually get applied so I ended up with something like:

A--B--C--F'--G'--H'  (master)
  \
    D--E--F--G--H  (EE4J_8)

Which still seems like something that I should be able to push.

What do you think I actually ended up with when I did the rebase?

And what did the "pull -r" change that into that allowed me to push?



And more importantly, what's the right way to rebase a branch onto master such that I can always push the master?

Do I always have to do a merge instead of a rebase to make this work?



Back to the top