This question already has answers here:
How do I revert a Git repository to a previous commit?
(41 answers)
Closed 4 years ago.
I realize this isn't directly a coding question, but GitHub is widely used and I haven't seen how to do this, so I figured I'd ask as I'm trying to figure it out.
Using GitHub how do I go about backtracking a development branch to a previous push point?
For example, let's say I have a dev branch and I push faulty code, how do I backtrack to a previous point in that branch in the event I need to?
I'd prefer to see how to do this from the command line, but in the web UI is fine as well.
Assuming your branch with the bad commit(s) has already been published to GitHub, and other users may have already pushed it, then you typically would not literally rollback that branch. Instead, you would use git revert to functionally undo the bad commit:
git revert 1a7h3jxk # where 1a7h3jxk is the SHA-1 hash of the bad commit
git revert actually adds a new commit which functionally undoes the commit you specify as a parameter. It also allows syntax for specifying a range of commits.
If you really want to formally "backtrack" your branch, you could do a hard reset to remove the bad commit(s). For example, to actually remove a single bad commit you could do:
git reset --hard HEAD~1
git push --force origin your_branch
But note carefully that doing a hard reset means that you are rewriting the history of your branch. This means you have to force push (read: overwrite) the version of the branch on the remote. As mentioned above, this option should not be used if anyone shared this branch besides you.
Related
A PR was accidentally merged into main before it had been properly sanitized which I think has resulted in their being no revert option. The lack of an option suggests that it is not possible/simple?
https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/reverting-a-pull-request
I have write permissions to the repo in question.
A revert is just a commit like any other commit. So, you can certainly revert the merge commit and push that, possibly as a PR if you're not able to push directly to main.
However, note that this reverses the effect of the merge without undoing the topology. You won't be able to merge those same commits again later.
In theory you can force main to go backwards to a commit before this bad merge took place, erasing the unwanted commits since then, or force main to point directly to the commit at the end of the good branch — namely by using a hard reset. But in practice, where you're sharing this repo with others, that would be a pretty terrible idea.
I am using git on VS2019
I was wondering if there is a way to remove old commits but always keep the latest code. The reason is that when I work on a big change, I do a lot of commits after checking every small step but at the end it is annoying when I click on view history and need to search an old commit to compare the changes. I would like to remove specific commits but leave the changes. In that way I will see on history only the main milestones of the developing process. There is a way to do that??
It sounds like in these scenarios, you're developing a new feature, in which case you should be using a branch+pull request approach to development. During the pull request, you can do a squash merge. It's not all in the command line, but that might be for the best anyway.
If you're already working within a feature branch, then I like VonC's approach.
It seems that you want the git rebase feature.
If you know how many commits you want to squash together, you can use
git rebase -i HEAD~N
You can also do it in interactive mode:
git rebase --interactive HEAD~N
Be aware that if you merging commits you have already pushed, you may have trouble with your next push.
For more details, see: https://www.internalpointers.com/post/squash-commits-into-one-git
You can follow a workflow similar to "Git better with fixups " from Atul Sharma
For the commits which are incremental improvement for the same step, use git commit --fixup small step, which allows you to "do a lot of commits after checking every small step".
(You can see it in Git Extension in Visual Studio)
But at the end, you can cleanup all those small steps with git rebase --interactive --autosquash <First step commit> (assuming you have not pushed those commits yet)
That way, you end up with a cleaner history.
There is a library with a branch named dev which I created a fork of here. I then made a commit to my fork so that it would better suit my needs, and I intend to make further commits in the future. However, as the library is still in development I would also like my fork to stay up to date with the changed made in the original dev branch so that it has all of the latest bugfixes and such. Is it possible to sync the two branches while keeping my personal changes?
Edit:
I've looked at the possible duplicate and it seems like an appropriate answer but I just want to clear up one thing before I accept it - I need to sync to just the dev branch and not the whole repo, so would I do git rebase upstream/dev? What does git rebase upstream/master even do?
You'll want to periodically rebase your fork. Alternatively, you could merge the changes in if you'd like to preserve the history.
How do I go back to a previous build? For example going back to the July 30 state?
There are a number of ways to functionally undo a series of commits in Git. But given that the branch in question is published, and likely shared by several people, I would recommend using git revert here. git revert adds new commits on top of your current branch which undo previous commits. These revert commits can be thought of as mirror images of what was done in previous commits. Something like this should work:
git revert 00bfe1b^..a013402
This should add two commits, one to undo the Aug-9 commit and one to undo the Aug-13 commit.
As a side note, you could have also done this:
git reset --hard HEAD~2
This would have completely nuked the two commits on top of Jul-30. However, this involves rewriting the history of the branch, which isn't desirable if other people may already be sharing this branch with you. In this case, just play it safe and use git revert.
To view (browse the file tree) the repository state at a certain commit given at least the first four characters of commit's hash, the following URL schema for GitHub can be used (at the time of writing):
https://github.com/{username}/{repository name}/tree/{hash}
If you want to hard reset your GitHub repository to a specific commit, do a git reset --hard {hash} in your local (stored on your computer) repository then force push it to a remote repository (like GitHub) via git push --force.
Of course, hard resets are dangerous. You can git revert or git reset and stash unstaged changes, and I'm sure there are other ways to achieve similar effects.
So, I'm new to Mercurial, and on my first try I screwed up.
Before pushing my data, I tried to merge with one branch (which I think was an old branch)
Instead of pushing it properly to change from "draft" to "public" I manually changed it from Tortoise by using the change phase from "draft" to "public"
I thought it meant that it would be placed in the repository, but when I went to the actual repository (on Bit Bucket) I couldn't find it.
So what happened, is I think I never made a push.
This is causing me an issue to make new changes, because when I tried committing other files, merging it with other branches and pushing it to the repository, i get the error:
searching for changes
remote has heads on branch 'branch one' that are not known locally: 62bf86f93d4f
abort: push creates new remote head 7edef5d2e2e5 on branch 'branch one'!
hint: pull and merge or see "hg help push" for details about pushing new heads
[command returned code 255 Thu May 27 14:43:44 2015]
So I think the solution would be to merge with the original draft (which is now public)
Thus my question: Is it possible to still merge and push a revision that was already deemed "public", even if I can't find it in the repository on bitbucket?
The phase of your commit (public vs. draft vs. secret) has no relevance for whether the commit can be merged. The difference between draft and public only affects whether the history involving the commit can be altered (e.g. via hg commit --amend or hg rebase). Public revisions are considered immutable, draft revisions can still be altered.
You can still merge and push. In theory, if you are positive that you didn't push the commit, you can also safely change the phase back to draft. However, that would be pointless [1], because pushing the merge will immediately make it public again [2].
[1] It can be useful if you use hg pull --rebase, but if you don't know what that does, you probably shouldn't use it.
[2] Unless you push to a non-publishing repository, but that's unlikely unless your group is using the evolve extension. If you don't know what a non-publishing repository or the evolve extension is, you don't need to know.