0

I have a few remotes, and an origin at github. I did several commits at one remote (A) that I pushed to origin but have not pulled to another remote (B).

I.e. Both remote A and origin are at C3:

C1->C2->C3

Remote B is at C1. I want everyone back at C1 so the commit chain looks like:

C1->C2->C3->C1

Now I want to revert everything to the state B is at (C3) using revert. But to do that, I need the commit code or hash or whatever it is called. I tried git show-ref and git for-each-ref but they display some very long hash, not the short codes that I believe signify each commit, which I would use in revert?

How do I find that code for the latest local commit on B, so that I can use it for revert and then push to origin?

From what I understand, I should be able to do git fetch at B to update my remote-tracking branch. And then I should be able to do a revert and push to origin, and then on my other remotes pull to get everything on the same page. Right?

Buttle Butkus
  • 9,206
  • 13
  • 79
  • 120

3 Answers3

1

It was hard to follow, so I hope I understand the question correctly.

Hashes

First of all - the short and long hashes are the same, and both represent a single commit. The short hash is simply the first few letters of the long hash. Statistically, the short hash is unique enough the distinguish between commits.

You can even use shorter hashes (I think 4 characters is the minimum length). As long as there is only one long hash that matches it.

Example on test repository I created with one commit only:

git log --oneline
8ade0365763ae62667cbbf3aeb3c1753ac956450 Test

git show 8ade

Reverting

It seems to me that the way you are suggesting is correct.

fetch and rebase on B. revert all the last changes. You don't need git show-ref a simple git log --oneline should be enough. push the changes back to origin.

So a complete flow on B machine:

git fetch
git rebase origin/master
git log --oneline
git revert <hashs you want to revert>
git push origin master

Force Pushing

Another option is to force push the B repository to the remote repository:

git push origin master --force

This will remove C2/C3 and their history from the remote repository. This push is a bit risky. I suggest reading about it a bit more before doing it: Force "git push" to overwrite remote files

Community
  • 1
  • 1
Igal S.
  • 13,146
  • 5
  • 30
  • 48
  • I know I didn't explain it very clearly. My latest commit on B machine appears to be: b0fa2, and I want everyone to revert to that commit, including origin. So wouldn't I fetch, then revert immediately, then push? Wouldn't fetching and rebasing move me forward to where origin is (2-3 commits ahead of where machine B's repo is)? – Buttle Butkus Dec 13 '15 at 07:23
  • I updated question to hopefully make it a little clearer. When I do `git show-ref` it is showing local commits, right? so my `bofa2` commit is the latest local commit? When I look at my github repo, I can see that commit hash on Nov 11th, and then two more after it. So it seems right. – Buttle Butkus Dec 13 '15 at 07:29
  • `fetch` only brings new objects from origin. It doesn't change your working directory. So you will not be able to `revert` anything. `pulling` will move you ahead, but that will allow you to revert the commits you don't want. An alternative will be to force push from repository B `git push -f` - but that i not advisable. – Igal S. Dec 13 '15 at 07:52
  • there is not much value in any of the commit history on this branch. I'm basically just trying to get it to a place where I can set a starting point. Once I do, then I'll obliterate all the past commits and set that to the first commit on this branch. So I will do whatever is easiest at this point. Do you think I can just do a `pull`, `revert`, and then `push`? (also `git log --oneline` shows the abbreviated hashes I was looking for, thank you) – Buttle Butkus Dec 13 '15 at 08:30
  • Yes. I think that is the way to do it. – Igal S. Dec 13 '15 at 08:33
  • One thing I'm worried about - untracked files. My goal is to revert to C1 and then unignore a bunch of untracked files and add them to the repo. If C2 also begins to track them, and C3 deletes them, will reverting to C1 where they are not tracked restore them? – Buttle Butkus Dec 13 '15 at 08:51
  • Ahm... I am not sure about it. It sounds to me that it would cause you conflicts in the `pull`, but I really not sure. If you are really just want to completely get rid of C2/C3 including their history. consider the `git push origin master --force` option. – Igal S. Dec 13 '15 at 09:09
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/97753/discussion-between-buttle-butkus-and-igal-s). – Buttle Butkus Dec 13 '15 at 09:13
0

It seems that there is a terminology confusion. If branches A and B are on your local machine, they are not called remotes. My interpretation of your situation: you have a remote repo and two local branches: A and B. If this is the case, then

git checkout A
git log
// find the commit you want to revert and copy it's hash
// format is like:
//  commit commit_sha <- that's what you need to copy
//  Author: ... 
//  Date:  
//
//        Commit name here
git revert commit_sha
git push
git checkout B
git pull

In your case you need to revert 2 commits before doing the push step: C2 and C3

Tim
  • 2,008
  • 16
  • 22
  • The branch is named 'legacy', from a private repo on github. It is checked out on several different machines right now, including machine A and machine B. Machine A has done some commits and pushed them to origin (github). Machine B is behind by two commits, but I actually want to revert everyone to that commit (b0fa2f6). Sorry, I'm pretty new to git and still not clear on all the terminology. – Buttle Butkus Dec 13 '15 at 08:45
  • Right, that's what was my interpretation. So your options are: 1) rewrite the history so that c2 and c3 disappear from history (the rebase solution); 2) revert c2 and c3, so that you will end up in the state of c1, but history is retained; 3) crete commit c4 which is essentially restores the state c1 (exussum's solution); I personally prefer 2) because it retains the history and captures the intent of what you're doing (reverting rather than moving forward to the same state). Does it make it any clearer? – Tim Dec 13 '15 at 19:58
0

First the short and long can be used as the same thing. So it wouldn't matter which you used.

It seems you want to add a single commit after c3 to get the code back to c1's state.

Personally i would check out c1's code

 git checkout c1 -- .

That checks out the code as it was in c1 you can then commit the result without rewriting history

exussum
  • 18,275
  • 8
  • 32
  • 65