简体   繁体   中英

Undo git pull from remote branch on a fresh git repository to a state before git pull

In short:

Can I reset my code to a state before I do a git pull after pulling code from remote branch on a fresh git repository ?

Long story:

I have two folders containing scripts, one folder represent another version of files inside the other folder. To apply version control, I start by creating a git repository in github with folder that has less revision compared to other folder, and create two branch with the same content to represent both folder.

To synchronize folder that has the latest revision to the remote branch, I do the following in that folder:

git init
git remote add origin [GITHUB_REPO]
git pull origin [BRANCH_NAME]:[BRANCH_NAME]
git add .
git commit -m "Latest revision."

I have tested the workflow several times before and there seems like nothing's wrong until I later on realize that right before git add . I run git status and no modification is shown, it only shows new untracked files, which is weird.

I need to undo to a state before I do git pull , because I realized that some of my files gets overwritten with remote, but since pull is the first action, and no commit before that, I can't reset to anything before pull .

This is the result of git reflog show :

edbfd0d HEAD@{0}: commit: Import code from development environment.
da39602 HEAD@{1}: checkout: moving from master to development

What I have done is:

git reset HEAD@{1}

And this doesn't solve the problem, it only undo the last commit, and overwritten files from git pull still doesn't come back. If it helps, the version of git on the server is 1.7.1, and on my local machine is 1.8.2.1. No wonder they act differently.

--

After further research, I found that the behavior of git pull in the server is different from my local development machine. It seems like in the server git pull automatically merge, while in my local development tells me there are files that might be overwritten on merge.

This causes files in the server automatically uses the less revised version on git pull on existing file with untracked files, while in my local development I can add the modified file and use the updated version.

There are two possible scenarios, depending on what git pull did. If the merge phase of git pull resulted in a fast-forward merge, then, immediately after the git pull , you can do this:

git reset --hard HEAD@{1}

This will reset HEAD and your branch pointer back to where it was immediately before you ran git pull . If you've done other things since the git pull , you may need to run git reflog HEAD and decide which entry you really want to reset back to.

If git pull created a new merge commit, either because a fast forward was not possible, or because it was requested to do a non-fast-forward merge, the above command will still work. However, in this case, you could also just reset back to the first parent of the current commit with this command:

git reset --hard HEAD^1

Again, though, if you've done other stuff in between, you may need to check your reflog, and use the first command instead with a number other than 1...

I do the following in that folder:

 git init git remote add origin [GITHUB_REPO] git pull origin [BRANCH_NAME]:[BRANCH_NAME 

Actually, that's not a good idea. One important rule with git is that you should never perform complex operations with a "dirty" working tree (ie with files that are not checked in).

In this case you created a repo in a directory with files in it, but did not commit the files. So the files are unknown to git, and thus git status shows them as "untracked". Now git pull will automatically try a merge, and merging with a dirty tree is problematic. git tries not to overwrite any data, but if the merge does not turn out as you wanted, there's no easy way to undo some of the changes, because the old version of the files was not committed.

So a better approach would be to first do the init/remote add/pull in an empty directory (or to just clone the remote repo):

git clone [GITHUBREPO]
git checkout BRANCH_NAME # note: This will create a local branch from the remote

That gives you a clean copy of the remote branch. Then you copy over the files from the folder with the lastest version, to create the intended new state of the branch:

rm oldfiles; cp -a ../folder2/* . # or similar

Then you commit all this:

git add .
git commit -m "Files from folder2"

At that point you once again have a clean working tree. Now you can merge with other branches, or push your changes, or merge in more branches, without fear of losing data. If things go wrong, you can always go back to the old commit.

Note:

The problem is my files gets overwritten with remote branch, and I can't undo to a state before I pull, because that's the first action

That should not normally happen. If the git pull causes a conflict with local, uncommitted files (as in your case), git pull should abort with an error. Like this:

error: Untracked working tree file 'myFile' would be overwritten by merge.

If it did not, then maybe git is configured to ignore these conflicts (this is, I believe, possible, though not the default). At any rate, if you never merge with a dirty working tree, that should not be a problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM