Your question is very broad. There are many, many possible scenarios with several alternative solutions, one with both advantages and disadvantages. Still, I see three important scenarios to consider:
- you want to return your repository local to a specific point;
- you want to return a repository public to a specific point
- you want to go back to a specific point of history to take a test, but you don’t want to change history.
Let us see them, then.
Rewind local repository
Consider this repository on Github. Let’s make some improvements to the program. First, we clone the repository locally and edit it.
First, let’s add one shebang:
$ git diff -U1
diff --git a/add.py b/add.py
index 77d557c..2bb03ed 100644
--- a/add.py
+++ b/add.py
@@ -1,3 +1,4 @@
+#!/usr/bin/env python
import sys
$
$ git com -am "Adding shebang line"
[master 3c1dd69] Adding shebang line
1 file changed, 1 insertion(+)
Then we’ll make the exit more explanatory:
$ git diff -U1
diff --git a/add.py b/add.py
index 2bb03ed..3287cc7 100644
--- a/add.py
+++ b/add.py
@@ -6,4 +6,4 @@ def add(a, b):
a2 = int(sys.argv[2])
-print add(a1, a2)
+print "%d + %d = %d" % (a1, a2, add(a1, a2))
$
$ git com -am "Making output readable"
[master 3cba3f9] Making output readable
1 file changed, 1 insertion(+), 1 deletion(-)
Finally, we add a greeting:
$ git diff -U1
diff --git a/add.py b/add.py
index 3287cc7..676b124 100644
--- a/add.py
+++ b/add.py
@@ -3,2 +3,4 @@ import sys
+print "This is the lame calculator. Hello!"
+
def add(a, b):
$
$ git com -am "Greeting"
[master a41916f] Greeting
1 file changed, 2 insertions(+)
We’re ready to upload the changes to Github, but it’s decided that the second and third changes are a bad idea. To undo it, as it only exists in your local repository, we can use git reset
. First, we have this history:
$ git log --oneline -n4
a41916f Greeting
f69d7d0 Making output readable
3c1dd69 Adding shebang line
cf629bc Removing spurious line
Then we use git reset --hard
:
$ git reset --hard cf629bc
HEAD is now at cf629bc Removing spurious line
The result will be:
$ git log --oneline -n4
cf629bc Removing spurious line
e4eccaf Using better names
b0d6449 Using proper name
e0e3713 Using variables
Now yes! We can make our own push happy.
Rewind public repository
Well, before we make our own push, We noticed that there are already wrong commits on Github! The commit 0b75b1 renaming b
for a2
within the function add()
, where this shouldn’t be done. Commit e88170 is even worse, turning addition into meaningless subtraction!
When to rewind public repositories almost we can never use git reset
. If we used git reset
, person who cloned our repository would have serious problems synchronizing with it again. The solution in this case is git revert
. To do this, simply pass the range of commits to be reversed, starting from the last commit to be removed and ending with the first commit to nay be removed (e88170). That is, you must pass the interval f187f6..e88170
:
$ git revert --no-edit HEAD..e88170
[master b77fd51] Revert "Using subtraction"
1 file changed, 1 insertion(+), 1 deletion(-)
[master bf5d6e0] Revert "Using better names"
1 file changed, 4 insertions(+), 4 deletions(-)
What is the difference to the git reset
? Well, instead of deleting commits, it adds new commits undoing old ones. If you look at the last commit, it will be the reverse version of the first reverse commit:
$ git show -U1
commit bf5d6e0a64916f9b4a40975c6e8ae519e682d37d
Author: Adam Victor Nazareth Brandizzi <[email protected]>
Date: Fri Jun 6 13:01:01 2014 -0300
Revert "Using better names"
This reverts commit 0b75b1fbbf6858bd5fe3c46a51dda7ea424bd84b.
diff --git a/lamecalc.py b/lamecalc.py
index 3edf375..9c3a009 100644
--- a/lamecalc.py
+++ b/lamecalc.py
@@ -3,7 +3,7 @@ import sys
def add(a, b):
- return a+a2
+ return a+b
-a1 = int(sys.argv[1])
-a2 = int(sys.argv[2])
-print add(a1, a2)
+a = int(sys.argv[1])
+b = int(sys.argv[2])
+print add(a, b)
Now yes! We can do the push reversals. Our past mistakes will remain visible, but we will not break repositories of our followers.
A very cool thing from git revert
is that you don’t need to use it only in the last commands. If you only want to reverse the commit 0b75b1
, could do it:
$ git revert 0b75b1
Of course it could give conflict, but in this case it was only to solve it, as it does with any conflict.
Go back in time to do an experiment
git reset
back the repository and causes the current branch to point to the chosen commit. We don’t always want this. For example, suppose we don’t know which commit causes our program to show subtraction instead of addition. We suspect, however, that the problem did not exist in the review f187f6
. In this case, just checkout this review and test:
$ git co f187f6
Note: checking out 'f187f6'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
git checkout -b new_branch_name
HEAD is now at f187f65... Using variables
Ready! In our current state, there is no more commit that we wonder:
$ git log --oneline -n5
f187f65 Using variables
f8f7118 Reading from parameters
e70e491 Moving to function
bbfb15d Adding operation
dd958e3 Initial commit
$
[13h13 adam@adam:~/sandbox/lamecalc] $ git branch
* (detached from f187f65)
master
We tested and found that the problem really didn’t exist then:
$ python lamecalc.py 2 2
4
On the other hand, our branch master
was not changed:
$ git log --oneline -n5 master
e881705 Using subtraction
0b75b1f Using better names
f187f65 Using variables
f8f7118 Reading from parameters
e70e491 Moving to function
But now that we know which version works, we can get back to the master branch with git co master
and then apply git revert
to wrong commit.
The sky is the limit
This answer is just the tip of the iceberg. There are other ways to return to a point - git rebase
iterative, checkout with -b
etc. - each one with its challenges. Boy, even the ones I presented here are completely explained! Still, I think we can already give an idea. Anything, we can increase the question later too, right? :)
https://answall.com/a/98587/153104 Better answer. Thank you! You really helped.
– Carlos Wagner