Question

So I'm working on a project that sometimes has long build times, and the build is clobbered very often. If I have an older branch with some work going on (which has been committed, but is based on an older parent), running git checkout oldbranch changes the working dir to represent all the old code, which makes me need to run a full build again.

However, usually I've only modified one or two files, and the rest don't need to be reset. What I'd like to do is to rebase this branch to the current master head, and preserve those changes to the files.

Basically, if a.rs and b.rs have been modified, then I need a way of making these changes base themselves onto the current head, without touching any files other than those two.

Is there a git-ish way of doing this? Currently I'm juggling patch files to do this.

Was it helpful?

Solution 4

NOTE: For the straightforward solution for the exact problem in the question look for the answers below, they are simpler.

For the more general problem of "I want to make some changes without messing up my working directory", keep reading.

See the comments about git worktree add if your repo is very big.


Clone the repo, make rebase in cloned copy, and push it back.

If you are inside your repo, it should be:

cd ..
git clone <name_of_your_repo_directory> tmp_repo
cd tmp_repo
git checkout origin/oldBranch
git rebase origin/master
git push -f origin HEAD:oldBranch

In tmp_repo origin is name of your local repo, of course (the one you cloned).

Note: the effect will be such as doing

git checkout oldBranch
git rebase master

in your original repo, not as

git checkout oldBranch
git rebase origin/master

OTHER TIPS

Going through the same right now I learned git rebase allows you to specify two branches in one go, essentially making it git rebase <remote> <local>, eg.

git rebase origin/master dev

This performs a more efficient rebase where your files don't get all re-written (which is the case if you checkout the branch first). You still need to resolve merge conflicts first and you end up with a repository where your local dev branch is checked out.

This sounds like a good use case for git cherry-pick. Instead of checking out the branch and rebasing it onto your current branch, you can stay on the current branch and cherry-pick commits from the old branch.

If the branch you're cherry-picking from only consists of a single commit, you can even refer to it by its branch name, eg:

git cherry-pick old-branch

ie. take the most recent commit from old-branch and apply the changes to create a new commit (preserving the commit message, author, etc) on your current branch.

I checked the source code and unfortunately it looks like it always checks out the base commit so unfortunately I think the only way you could do this would be to clone the repo into another directory, rebase it there and then push the changes back into the original repo, and finally delete it.

Note that cloning a local repo to elsewhere on the same file system uses hardlinks for the files under .git so it's not actually as slow as you'd think.

Edit: actually a better alternative is to use a worktree, something like this:

cd <your repo>
git worktree add ../tmp <branch to rebase>
cd ../tmp
git rebase master
cd -
git worktree remove tmp

Note that you can only have a branch checked out in one worktree at a time.

if you have

-A---o---o---o---o---D
 \---B---o---C

and D is checked out (which I believe is your situation), you can

git cherry-pick B..C

to reach this:

-A---o---o---o---o---D---B---o---C

with C now being head, and without touching the files changed made in A..D

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top