Home > other >  How do I remove my change to a folder in a PR
How do I remove my change to a folder in a PR

Time:08-05

In a PR, I made changes to some folder dir1 in a bunch of commits:

commit1  changes to dir2, changes to dir3
commit2  changes to dir1, changes to dir3
commit3  changes to dir2, changes to dir3
commit4  changes to dir1, changes to dir3
...
commit30 changes to dir2, changes to dir3
...
commit40 changes to dir2, changes to dir3
...

Now I wish to take back all the changes I made in dir1. But I'm not the only person making changes to dir1 - other people have modified dir1 and merged the changes in master branch.
I have tried:

git checkout master
git pull
git checkout -
git checkout master -- dir1

but on PR page it still shows some changes in dir1 in my PR. I doubt that the comparison might be performed between my PR and the master branch at the time my PR was open. But anyway, how can I reset the folder dir1?

CodePudding user response:

Here are two ways to update the pull request:

Revert the undesired commits

Each commit affecting dir1 should be reverted, as explained in this post.

The revert operation creates new commits undoing the changes of previous commits.

Steps

  1. start from the branch which was used to create the pull request
  2. execute git log or git log --oneline in order to identify the commits which affect dir1 (other commands may be used for this)
  3. execute git revert <commit-sha> on each commit affecting dir1, in chronological order.
  4. push the branch again to the remote repository.

The pull request should be updated and only contain the desired commits.

Rebase the branch

An alternative solution, perhaps more suitable if there are many commits, is to do a mass undo using an interactive rebase.

This techniques rewrites the history of commits (which were already pushed to the remote), so it needs to be performed in a new branch.

steps

  1. start from the branch which was used to create the pull request
  2. create a new branch git checkout -b temp-cleanup
  3. use git log to identify a commit-sha earlier to the changes you want to undo
  4. execute git rebase -i <earlier-sha>
  5. a text editor opens up, showing the commit history. Delete all lines performing a change to dir1 (and do not change anything else to the file).
  6. save and exit
  7. push the newly created branch and create a new pull request using it as a base
  8. delete the older pull request.

CodePudding user response:

Here's the general method:

  • Step 1 is to find the commit before commit1 changes to ....

  • Step 2 is to run git checkout (Git versions before 2.23) or git restore using this commit hash ID.

  • Step 3 is to make a new commit.

In your own case, assuming this:

commit1  changes to dir2, changes to dir3
commit2  changes to dir1, changes to dir3

is an accurate summary of what you did, you can use commit1 directly, rather than finding the commit before commit1, because every commit holds a full snapshot of every file so the copies of dir1/* in commit1 simply match the copies of dir/* in the commit before commit1. However, as a shortcut, know that adding ^ or ~ as a suffix character to a commit hash ID means the parent of that commit.1

To use git checkout, use it just as you did:

git checkout <rev> -- dir1

To use git restore, run it with the -S and -W flags (--staged and --worktree if you want to spell them out the long way) and --source=rev. That is, if commit1 is the (abbreviated) hash ID a123456, you could write:

git restore --source=a123456^ -SW -- dir1

The purpose of the -- here is to make sure that the stuff on the left of the -- is treated as arguments to the command to select the commit that holds the files of interest and tell it where to put the restored files (for git restore; git checkout just assumes where to put them), and that stuff on the right of the -- is treated as the set of files to restore. Since dir1 doesn't look like a commit hash ID or a flag, we don't technically need the -- at all, but it's a good habit to get into, in case you ever want to restore a file named -f or some such.

The general idea here is that by adding a new commit that puts the files back, all the changes you made in between, that changed the files, become irrelevant when merging. Note that this does not work for git rebase (or GitHub's REBASE AND MERGE button), but only for git merge; for git rebase, you have much more work cut out for you.


1More precisely, <rev>^1 means the first parent of the specified revision, <rev>^2 means the second parent of the specified revision, <rev>^3 means the third parent of the specified revision, and so on. However, most commits have only one parent anyway, and omitting the numeric suffix after the ^ "means" 1. Some command line interpreters may require you to type ^^ rather than just ^ as the CLI itself uses ^ for quoting characters, so you need type two of them to mean one of them. You might want to use ~ for these CLIs since they don't have a special meaning for ~.

Similarly, <rev>~1 means the first parent of the specified revision, but <rev>~2 means the first parent of the first parent of the specified revision, while <rev>~3 means the first parent of the first parent of the first parent of the specified revision, and so on. That is, this counts commits backwards, one hop at a time, based on the number after the tilde ~ character. As with caret ^, an omitted number means 1.

This is discussed in greater detail in the gitrevisions documentation, which is worth a regular (weekly or monthly perhaps) read-through until you really "get it", which takes a long time with Git. There's a lot of stuff in here, so just pick one thing to work on at a time.

  •  Tags:  
  • git
  • Related