'Using the script from some particular branch in git

This question is maybe answered, but I couldn't find it.

I have a branch where I am working on and I didn't finish my work on this branch. Now I need to use prebuilt tool that is on totally different branch.

I don't have that script at all visible on my branch, but I need to run it in order to get something, to continue working on my branch. There are three problems here:

  1. I don't want to checkout to another branch. I want to work on my own branch all the time
  2. I don't want to commit anything before I finish
  3. I want to use something from another branch that is not visible on my own branch

How is that possible and is it possible at all?

git


Solution 1:[1]

There are many ways to deal with this. They all boil down to the fact that you're trying too hard, right now. ? Take it easier!

Let's start with this: Branches, in Git, are basically irrelevant; what matters are the commits. Commits hold two things: a full snapshot of every file, plus some metadata (information about who made the commit for instance). We won't go into any further detail here except to note that the contents of any given commit are 100% read-only: no commit can ever be changed, not even by Git itself.

When you do work in Git, you start by extracting some commit. That is, you run git checkout branch or git switch branch, or maybe even git checkout hash-ID. This extracts, from one specific commit, a full copy of every file. (The files stored inside commits are in a special, read-only, compressed, Git-ified, de-duplicated format that only Git can read and literally nothing can write, which makes them useless except for this extraction process.) But: which commit does this extract?

Commits are identified by hash ID. The hash IDs are big and ugly and impossible for humans to work with, aside from using cut-and-paste with the mouse or similar. So you can do that—as in the git checkout hash-ID case—or you can use branch names and other such names (tag names for instance). Each name is a way to spell one hash ID without having to type in the raw hash ID. A branch name essentially "means" the latest commit on the branch.

Now that you have the files from that commit, you work on / with them, run git add to update the proposed next commit, and run git commit, and Git makes a new commit and automatically updates the branch name (assuming you're using branch names). So that's the situation you're in right now:

I have a branch where I am working on and I didn't finish my work on this branch.

This isn't quite precise. What you mean is: you checked out some particular commit, by branch name, and you started working. You're not ready to make a new commit yet. You're still "on the branch" (so that any proposed new commit that you use to make a new commit will update the branch name to remember the new latest commit) and you'd like to stay that way.

Now I need to use prebuilt tool that is on totally different branch.

Let's make this one more precise as well. You mean that you want to get at some file (shell script, command, whatever) that's stored in some other commit. The hash ID of that other commit is stored in some other branch name, e.g., toolbranch.

Why all this matters

You can easily access any single file in any commit using git show or git cat-file -p. For instance, if you know the commit hash ID that you need is a123456 and the path name of the file stored in that commit is tools/sometool.sh, you can run:

git show a123456:tools/sometool.sh

and Git will dump the contents of that file, as stored in that commit, to the standard output. Using shell (bash/sh/zsh/whatever) redirection, you can get this output into a file:

git show a123456:tools/sometool.sh > /tmp/sometool.sh

and now you can run the tool from /tmp/sometool.sh.

(The git cat-file -p variant is:

git cat-file -p a123456:tools/sometool.sh > /tmp/sometool.sh

The git show one is a little easier to type in. Use git cat-file in scripts as it's a "plumbing" command; for normal human commands, use git show.)

What if I don't know the raw hash ID?

No problem! The branch name works just as well:

git show toolbranch:tools/sometool.sh > /tmp/sometool.sh

What if I need a whole bunch of files from toolbranch?

As long as your Git is at least version 2.5, and preferably at least 2.15, you can use git worktree add to add a whole separate working tree with that commit checked out:

git worktree add ../toolbranch

for instance. Now ../toolbranch contains the entire set of files extracted from the commit named via the branch name toolbranch.

Given that this gets every file out of the desired commit, it may be overkill for your situation. The git show or git cat-file -p variant is a much more refined tool (a lightsaber, or maybe bytesaber, instead of a blaster, in Star Wars terms), but sometimes just blasting your way through something is convenient.

(Use git worktree remove later to discard the added work-tree, or just leave it around if it isn't bothering you. The bug fixed in 2.15 has to do with leaving added working trees around for more than 14 days while doing work in them, so if you start doing work in the added working tree, and are going to let it take two or more weeks, make sure you have the fixed-up Git.)

Solution 2:[2]

Here is my proposed solution:

  1. Add your script to .gitignore to get it not committed. (If you plan to change it, you can force staging by git add --force).
  2. When you need to run it, checkout only that file by git check out <SCRIPT_BRANCH> <SCRIPT_FILE_NAME>.

By the step 1, the checked out file is not seen as a file to be staged.

Solution 3:[3]

You can find out the commit when your tool has been introduced (using git log or git blame <FILE>) . You can then use git cherry-pick to get this specific commit into your branch. If you don't want to commit these changes to your branch, you can use the -n flag:

git cherry-pick -n <COMMIT>

This brings your tool to the current branch without committing anything. You can execute the script and do what you want. Afterwards you can do git reset (unstage the cherry-picked stuff) and delete your files.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 torek
Solution 2 Antonio Petricca
Solution 3 Felix