Skip to content

Instantly share code, notes, and snippets.

@jussi-kalliokoski
Last active July 11, 2022 10:08
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save jussi-kalliokoski/4381703 to your computer and use it in GitHub Desktop.
Save jussi-kalliokoski/4381703 to your computer and use it in GitHub Desktop.
Cherry-picks commits from master that have changes to specified files.
$!/usr/bin/env sh
branch=`git symbolic-ref --short HEAD`
git checkout master
commits=`git log --pretty="%H" --reverse -- $*`
git checkout $branch
for commit in $commits; do
git cherry-pick $commit
done
@jussi-kalliokoski
Copy link
Author

The point of this is to extract the history of only certain files to a clean branch.

Usage:

Create the clean branch:

$ git checkout --orphan my-new-branch
$ git rm -rf .

Create an initial commit, because cherry-pick doesn't work on an empty head.

$ touch .dummy-file
$ git add .dummy-file
$ git commit -m "Initial commit"

Now, assuming you're still in the "my-new-branch" branch, run

$ git-pick-file.sh file1 file2 fileX

Then to make sure everything worked as planned, check

$ git log

@jwebcat
Copy link

jwebcat commented Mar 14, 2013

After some thought about this, Do you have any opposition to creating a new repo and doing a sparse-checkout ?

This way you could just checkout the files you want to a new repo. like so.

$ mkdir newRepo && cd $_
$ git init
$ git remote add –f <name> <url>
$ git config core.sparsecheckout true
# Configure sparse-checkout by listing your desired sub-trees in .git/info/sparse-checkout see my comment below:
$echo some/dir/* >> .git/info/sparse-checkout
$echo another/sub/tree/* >> .git/info/sparse-checkout
$ git pull <remote> <branch>
# you will now have only the files that you specified through your sparse-checkout file which has the exact same syntax as .gitignore files

check this out

# ignore all files in the root
/*
#except these files and dirs
!exceptHere/
!.gitignore
!readme.md
!resources/
# ignore everything in this dir 
koken/*
# except these
!koken/storage/
# ignore everything inside this dir
koken/storage/*
# except this dir
!koken/storage/themes/

now you can create quite a complex include easily.

if you want to run this in an existing repo just use

git read-tree -mu HEAD
  • also if you want to add more files from the repo that you did the sparse checkout from just edit the sparse-checkout file and run git read-tree -mu HEAD again to update the working tree.

What are your thought is this a more efficient way for you? I would LOVE to hear your thoughts.

@aigitia
Copy link

aigitia commented Apr 3, 2019

should not first line have #!/usr/bin/env instead of $!/usr/bin/env, i.e. hash instead of the dollar?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment