gitgit-branchgit-checkout

How to get just one file from another branch


I have a main branch with a file called app.js. I made changes to this file on an experiment branch.

I want to apply only the changes made to app.js from experiment onto the main branch.


Solution

  • git checkout main                 # first get back to main
    git checkout experiment -- app.js # then copy the version of app.js 
                                      # from branch "experiment"
    

    See also Undo working copy modifications of one file in Git.


    Update August 2019, Git 2.23

    With the new git switch and git restore commands, that would be:

    git switch main
    git restore --source experiment -- app.js
    

    By default, only the working tree is restored.
    If you want to update the index as well (meaning restore the file content, and add it to the index in one command):

    git restore --source experiment --staged --worktree -- app.js
    # shorter:
    git restore -s experiment -SW -- app.js
    

    As Jakub Narębski mentions in the comments:

    git show experiment:path/to/app.js > path/to/app.js
    

    works too, except that, as detailed in the SO question "How to retrieve a single file from specific revision in Git?", you need to use the full path from the root directory of the repo.
    Hence the path/to/app.js used by Jakub in his example.

    As Frosty mentions in the comment:

    you will only get the most recent state of app.js

    But, for git checkout or git show, you can actually reference any revision you want, as illustrated in the SO question "git checkout revision of a file in git gui":

    $ git show $REVISION:$FILENAME
    $ git checkout $REVISION -- $FILENAME
    

    would be the same is $FILENAME is a full path of a versioned file.

    $REVISION can be as shown in git rev-parse:

    experiment@{yesterday}:app.js # app.js as it was yesterday 
    experiment^:app.js            # app.js on the first commit parent
    experiment@{2}:app.js         # app.js two commits ago
    

    and so on.

    schmijos adds in the comments:

    you also can do this from a stash:

    git checkout stash -- app.js
    

    This is very useful if you're working on two branches and don't want to commit.