How to get just one file from another branch?

You want to retrieve a file from another branch, but you don't want to merge the whole branch into your current branch.

Setup

Let’s create a file named file1.txt in the main branch:

alina

alina git:( main ) echo "content for file 1" > file1.txt

alina git:( main ) git add file1.txt

alina git:( main ) git commit -m 'create file1'

[main 0ba2b3e] create file1

 1 file changed, 1 insertion(+)

 create mode 100644 file1.txt

alina git:( main ) git push

Enumerating objects: 4, done.

Counting objects: 100% (4/4), done.

Delta compression using up to 8 threads

Compressing objects:  50% (1/2)

Compressing objects: 100% (2/2)

Compressing objects: 100% (2/2), done.

Writing objects: 100% (3/3), 286 bytes | 286.00 KiB/s, done.

Total 3 (delta 0), reused 0 (delta 0), pack-reused 0

remote: . Processing 1 references

remote: Processed 1 references in total

To ssh://remote.mygit.com/gitpowerup/arenas.git

   c5c9016..0ba2b3e  main -> main

alina git:( main )

This leads to the following commit graph:

alina

0ba2b3ec5c9016mainorigin/mainHEAD

Now, let’s create a branch named b1 and switch to it. We can do this in a single command:

alina

alina git:( main ) git checkout -b b1

Switched to a new branch 'b1'

alina git:( b1 )

This leads to the following commit graph:

alina

0ba2b3ec5c9016b1mainorigin/mainHEAD

Next, we can create a file called file2.txt in the b1 branch:

alina

alina git:( b1 ) echo "content for file2" > file2.txt

alina git:( b1 ) git add file2.txt

alina git:( b1 ) git commit -m 'add file2'

[b1 e03c2c5] add file2

 1 file changed, 1 insertion(+)

 create mode 100644 file2.txt

alina git:( b1 ) git push --set-upstream origin b1

Enumerating objects: 4, done.

Counting objects: 100% (4/4), done.

Delta compression using up to 8 threads

Compressing objects: 100% (2/2), done.

Writing objects: 100% (3/3), 308 bytes | 308.00 KiB/s, done.

Total 3 (delta 0), reused 0 (delta 0), pack-reused 0

remote: 

remote: Create a new pull request for 'b1':

remote:   http://localhost:3030/gitpowerup/arenas/compare/main...b1

remote: 

remote: . Processing 1 references

remote: Processed 1 references in total

To ssh://remote.mygit.com/gitpowerup/arenas.git

 * [new branch]      b1 -> b1

branch 'b1' set up to track 'origin/b1'.

alina git:( b1 )

This leads to the following commit graph:

alina

e03c2c50ba2b3ec5c9016b1mainorigin/b1origin/mainHEAD

We can confirm that the branch b1 now contains these 2 files:

alina

alina git:( b1 ) ls -al

total 24

drwxr-xr-x   6 alina  staff  192 May 25 07:59 .

drwxr-xr-x   3 alina  staff   96 May 25 07:58 ..

drwxr-xr-x  13 alina  staff  416 May 25 07:59 .git

-rw-r--r--   1 alina  staff   39 May 25 07:58 README.md

-rw-r--r--   1 alina  staff   19 May 25 07:58 file1.txt

-rw-r--r--   1 alina  staff   18 May 25 07:59 file2.txt

alina git:( b1 )

Let’s switch back to the main branch:

alina

alina git:( b1 ) git checkout main

Switched to branch 'main'

Your branch is up to date with 'origin/main'.

alina git:( main )

Now, the main branch only has file1.txt:

alina

alina git:( main ) ls -l

total 16

-rw-r--r--  1 alina  staff  39 May 25 07:58 README.md

-rw-r--r--  1 alina  staff  19 May 25 07:58 file1.txt

alina git:( main )

How can we retrieve file2.txt from the b1 branch?

Solution

There are 2 ways to copy the file file2.txt to your branch.

The first option is to use the git show [branch's name]:[file's name] command:

alina

alina git:( main ) git show b1:file2.txt

content for file2

alina git:( main )

Then, you can redirect the output to a file and add it to your repository.

The second option is to use the git restore --source [branch's name] -- [file's name] command:

alina

alina git:( main ) git restore --source b1 -- file2.txt

alina git:( main )

Running git status will show that the file is now in your repository but not yet staged:

alina

alina git:( main ) git status

On branch main

Your branch is up to date with 'origin/main'.

Untracked files:

  (use "git add <file>..." to include in what will be committed)

        file2.txt

nothing added to commit but untracked files present (use "git add" to track)

alina git:( main )

You can verify that the content is the same as the one in the b1 branch:

alina

alina git:( main ) cat file2.txt

content for file2

alina git:( main )

Finally, it’s time to stage and commit the file:

alina

alina git:( main ) git add file2.txt

alina git:( main ) git commit -m 'retrieve file2'

[main a101304] retrieve file2

 1 file changed, 1 insertion(+)

 create mode 100644 file2.txt

alina git:( main )

and push the changes to the remote repository:

alina

alina git:( main ) git push

Enumerating objects: 4, done.

Counting objects: 100% (4/4), done.

Delta compression using up to 8 threads

Compressing objects: 100% (2/2), done.

Writing objects: 100% (3/3), 312 bytes | 312.00 KiB/s, done.

Total 3 (delta 0), reused 0 (delta 0), pack-reused 0

remote: . Processing 1 references

remote: Processed 1 references in total

To ssh://remote.mygit.com/gitpowerup/arenas.git

   0ba2b3e..a101304  main -> main

alina git:( main )

This leads to the following graph:

alina

a101304e03c2c50ba2b3ec5c9016b1mainorigin/b1origin/mainHEAD