Copying an untracked folder to another branch

2k Views Asked by At

Is there a way to copy an untracked folder to another branch?

I know you can copy tracked folders to another branch by doing something like this:

git checkout mybranch
git checkout master -- myfolder

But is there a way to copy a folder that isn't tracked on master, but is tracked on the branch I want to copy to?

I'm trying to do this for GitHub pages and I'm following this guide, but he commits to master and pushes it to upstream gh-pages. I don't want to do that. I just want my build to generate the docs and copy the untracked docs to another branch and then push them upstream.

3

There are 3 best solutions below

1
On BEST ANSWER

What you have here is a situation that you have some untracked files which conflict with tracked files in another branch. You'd like to switch to that branch, but checkout won't let you.

The "first level" solution in git is to promote these untracked files to the index:

git add folder

Now you still cannot check out to the branch. However, you are presented with a new possibility: you can git stash save the changes:

git stash save

Now you can switch to the branch, and do a git stash pop. At this point you can deal with merge conflicts, if any, followed by a git reset and you're done.

[Update: the git add is not necessary because git stash has an option to include untracked files!]

Let's work through a complete example, involving a single file called topicfile which exists only in a branch, and is created as a working file while on master, but with different contents:

~$ mkdir gittest
~$ cd gittest/
~/gittest$ git init
Initialized empty Git repository in /home/kaz/gittest/.git/
~/gittest$ touch emptyfile
~/gittest$ git add emptyfile
~/gittest$ git commit -m "starting repo"
[master (root-commit) 75ea7cd] starting repo
 0 files changed
 create mode 100644 emptyfile
~/gittest$ git branch
* master
~/gittest$ git checkout -b topic
Switched to a new branch 'topic'
~/gittest$ cat > topicfile
a
b
c
d
e
~/gittest$ git add topicfile
~/gittest$ git commit -m "topicfile"
[topic 875efc5] topicfile
 1 file changed, 5 insertions(+)
 create mode 100644 topicfile
~/gittest$ git checkout master
Switched to branch 'master'
~/gittest$ ls
emptyfile
~/gittest$ cat > topicfile
@
a
b
c
d
e
f
g
h
~/gittest$ git add topicfile
~/gittest$ git stash save topicfile
Saved working directory and index state On master: topicfile
HEAD is now at 75ea7cd starting repo
~/gittest$ git checkout topic
Switched to branch 'topic'
~/gittest$ git stash pop
Auto-merging topicfile
CONFLICT (add/add): Merge conflict in topicfile
~/gittest$ cat topicfile
<<<<<<< Updated upstream
=======
@
>>>>>>> Stashed changes
a
b
c
d
e
<<<<<<< Updated upstream
=======
f
g
h
>>>>>>> Stashed changes
~/gittest$ cat > topicfile  # resolve in favor of stashed changes:
@
a
b
c
d
e
f
g
h
~/gittest$ git add topicfile
~/gittest$ git reset
Unstaged changes after reset:
M       topicfile
~/gittest$ git diff
diff --git a/topicfile b/topicfile
index 9405325..bea0ebb 100644
--- a/topicfile
+++ b/topicfile
@@ -1,5 +1,9 @@
+@
 a
 b
 c
 d
 e
+f
+g
+h

At this point we can commit our topicfile changes to the topic branch, and the file is still not tracked on master.

Because there were conflicts in git stash pop, the stash still exists. We can clean that away with git stash drop.

The alternative to all this is to not only git add the untracked files to the index, but to git commit that to make a proper commit. Then we can cherry pick the commit into the branch. If we don't want those files tracked on master, that is okay: we can later git reset --hard HEAD^ on master to eliminate that commit.

3
On

If the folder is untracked, then you can simply checkout the other branch and the untracked directory is not touched.

0
On

Should you find yourself here because you are trying to push Sphinx documentation in your untracked docs/_build folder to your gh-pages branch, Here is what I did in my GitHub Action

      - name: Init new repo in dist folder and commit generated files
        run: |
          cd docs/build/html/
          git init
          touch .nojekyll
          git add -A
          git config --local user.email "[email protected]"
          git config --local user.name "GitHub Action"
          git commit -m 'deploy'
      - name: Force push to destination branch
        uses: ad-m/[email protected]
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          branch: gh-pages
          force: true
          directory: ./docs/build/html

Which is doing something along these lines if I were working from my local machine.

cd docs/_build/html/
#git init #run first time only
#touch .nojekyll #run first time only
git add -A
git commit -m 'deploy'
git push -f <url of the repo on GitHub> master:gh-pages
cd ../../..
git fetch --all
git checkout gh-pages # now update the local gh-pages branch
git pull

The first time, Git complained that the histories of origin/gh-pages and local/gh-pages were incompatible so I did this. I backed up gh-pages since I am always a bit frightened of git reset --hard

git branch backup-ghp
git reset --hard origin/gh-pages