Handling temporary changes (not to be committed) in Git

↘锁芯ラ 提交于 2019-12-12 07:10:18

问题


Often while working on a branch I need to introduce some "temporary" changes (such as additional debugging info, or a change which lets me better observe the thing i'm actually working on).

About these "temporary" changes:

  • I want them in my working copy of my branch, because they help me to work on the actual change,
  • I don't want them committed to the branch, because the branch is going to be merged into master some time and they're not production code.

Currently I just keep them as unstaged and I skip them manually when staging every commit. However I can't stay with this solution because:

  • All the time I have to remember which files I need to skip,
  • Someday I'm going to end up with 2 changes in one file, one being temporary, one to be committed, and it's going to be really troublesome.

How should I deal with it?


gitignore is obviously out of the question because I don't want to ignore the whole files and I'm still interested in changes from other committers (I need to rebase the branch to master from time to time).


回答1:


I typically deal with this by using:

git add -p

... to stage changes hunk-by-hunk. Then you just have to make sure to press n for your debugging changes.


If I have more involved changes of this type, I'll create a branch called something like local-changes with a commit at its tip that introduces the debugging code. After creating a few more commits, I'd then use:

git rebase -i master

... to reorder them so that the commit with the local changes is at the tip again. Then to update master and return to the local changes branch, you can do:

git checkout master
git merge local-changes^
git checkout local-changes



回答2:


Try git update-index --assume-unchanged <file>. This way git will not add the file to the index when using git add or git commit -a.

EDIT: This doesn't allow you to deal with the case of having one file with both temporary and permanent changes.




回答3:


You can use

git stash

to save it into a temporary spaces. After doing your merge, you can use

git stash pop

to load back your temporary changes into your working-directory.




回答4:


Here's a way to deal with this that, once set up, only requires you to remember one step to set it up, and one step before each push.

The setup:

git branch tempChanges  [branch for temporary changes]
  [create your temporary changes]
git add -A
git commit

Note the sha for that commit. Then switch to your working branch, and:

git cherry-pick shaOfTempChangesCommit

Now you have the changes on your working branch. Do your work and make commits. Then, before you push:

git rebase -i

You'll see something like this:

pick bfd4d2e This first commit is your temporary changes.
pick 186a99d Some stuff done on the working branch.
pick ec871c6 More stuff done on the working branch.
(etc.)

Delete the line with your temporary changes. Then save and exit. Your history will be rewritten to exclude the temporary changes. (The changes will still exist in the tempChanges branch.) Once that's done, do any testing you need to and then git push.

When you're ready to work again, you can pull the temporary changes back onto your current working branch (or a new working branch):

git cherry-pick shaOfTempChangesCommit

So, in sum, all you have to remember in this method is

  • after you create a working branch

    git cherry-pick shaOfTempChangesCommit

  • after you're done working and ready to push

    git rebase -i [to remove the temporary changes before you push]




回答5:


I usually put all my debug code in its own commit, then before I do the merge, I revert that commit. I've used some variation of most of the other answers at times, but I like this one for its simplicity and the fact that it preserves my development history. Yes, I don't want my debug code in the final product, hence the revert, but if testing finds an issue I want to be able to reinstate that debug code for further work.




回答6:


I've found a clean solution to this problem: (pardon my ascii-art). It requires an additional branch for the topic branch. (this has flaws and is being disputed/corrected, see comments)

The work looks like this initially:

master
     \
      \
     commit1  ---- commit2 ---- "branch"

Work is done on "branch".

To introduce some temporary changes:

  • create branch "branch-temp" from "master"
  • commit the temporary changes there
  • rebase "branch" from "master" onto "branch-temp"

The repo now looks like:

master
     \
      \
     "branch-temp" ----- commit1 ---- commit2 ---- "branch"

Work is now happily continued on branch and the temporary changes are not visible in the status.

To change or extend the temporary changes:

  • checkout branch-temp
  • commit --amend the temporary changes there - this is wrong, since it makes "branch-temp" diverge

To merge the changes from branch to master:

This is just a bit more tricky. We want to merge in all changes, except the changes introduced by "branch-temp". My idea is:

  • run a normal merge from "branch" onto "master"
    (we now have a merge, but with some unnecessary temporary changes - let's remove them)
  • git revert --no-commit branch-temp
  • git commit --amend
    (these two steps should modify the merge commit, so that it no longer contains the changes from branch-temp)



回答7:


What about writing a simple shell script that will patch and undo your debug changes on request (and then make it as a git alias).

E.g.

git apply-my-debug
...
do coding
...
git remove-my-debug
git add .
git commit -m "Don't worry about debug changes"



回答8:


To avoid cluttering up your staging area as you're creating a feature, commit your debug changes with a bright blinking warning that they should not make it into the final merge:

#warning - DEBUG ONLY - DO NOT MERGE

print(debugInfo)

#warning - DEBUG ONLY - DO NOT MERGE

When you're ready to merge the branch, if you've forgotten about them, these changes will be caught by you or someone else in the code review of your pull request.

You'll then have different ways to remove the debug commits:

  1. revert the specific debug commits. This will retain their history in the branch.

  2. cherry-pick the good commits. This will remove the debug commits entirely.

  3. Something more complicated such as rebase -interactive to remove the commits in-place.




回答9:


GIT's stash functionalities provides exactly what you're asking for. At least for the "keeping" part. Making the good/bad-selection when committing cannot be avoided like this.




回答10:


I tend to keep uncommitted changes like that. I simply always use git add -i or git add -p to stage changes (unless I am sure I want all changes the tree has). That way I review all the changes I do want committed and easily skip temporary ones. It also helps to stage changes you know you'll want committed early and keep them staged or even commit them and than add more changes with git commit --amend.



来源:https://stackoverflow.com/questions/7147789/handling-temporary-changes-not-to-be-committed-in-git

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!