Git checkout and merge without touching working tree

后端 未结 4 1947
面向向阳花
面向向阳花 2020-11-30 00:43

Say I have a feature branch, into which I merge upstream changes prior to pushing my changes back:

git branch feature1
... [edit my code]
... [commit]
git fe         


        
相关标签:
4条回答
  • 2020-11-30 01:11

    A simple and safe way to do this—without a push or a forced update—is to fetch feature1 into master:

    (feature1)$ git fetch . feature1:master
    From .
       4a6000d..8675309  feature1   -> master
    

    The trick is using . to get the local feature1 ref. This is safer than forcibly updating the master branch, since it ensures the update is a fast-forward. (See the <refspec> parameter in the git-fetch documentation for details.)

    Now that feature1 and master are the same, switching between them will not touch any files:

    (feature1)$ git checkout master
    Switched to branch 'master'
    (master)$
    
    0 讨论(0)
  • 2020-11-30 01:24

    There is no way that merge (or rebase) can work without touching the working directory (and index), as there can be merge conflicts that have to be resolved using working directory (and/or index).

    You can always have another clone (perhaps using alternates, or symlinking objects directory, to save disk space), or another working directory with contrib/workdir/git-new-workdir. Or use a tool such as ccache.

    Edit: nowadays git worktree is a part of core Git, no need for external tools (at least since git version 2.6.0).

    0 讨论(0)
  • 2020-11-30 01:34

    [Edit] This is only a partial solution / workaround. See the actual answer by @djpohly below.

    Firstly, you can push from anywhere. Doesn't matter what you have checked out, or whether the commits you want to push are in master.

    git push REMOTE_REPO feature1:master
    

    see git help push

    Hint: git push remoteRepo localRef:remoteRef

    As for bringing master to where you are now without fiddling with your working copy... You can force it like so:

    # (while still on feature1 branch)
    git checkout -B master origin/master
    

    But this does a hard reset on master. ie it doesn't check for fast-forward.

    0 讨论(0)
  • 2020-11-30 01:37

    If you only care about a couple of files and you're using Unix, you can change manually fix the mtime after the fact using touch -d <timestamp>. Make sure you use ls --full-time to get the timestamp, as the default display lacks precision.

    For example, imagine you're using Docker to build an image for a Python-based web app. If the requirements.txt file changes it takes a long time to rebuild, because it has to download a bunch of 3rd-party libraries and compile them. Simply reset that file's mtime after merging:

    ls -og --full-time src/requirements.txt
    # -rw-r--r-- 1 282 2015-11-04 20:03:28.918979065 +0400 src/requirements.txt
    
    git checkout master
    git merge --no-ff feature-foo
    
    touch src/requirements.txt -d "2015-11-04 20:03:28.918979065 +0400"
    
    0 讨论(0)
提交回复
热议问题