Regarding out Git workflow, we create a branch off the master that we use for a specific sprint, and each work item in that sprint branches from it. So effectively, the branch/merge flow would be:
master
| \
| sprint42________
| | \ \
| | item1 item2
| | ___/ /
| |/ /
| | _________/
| |/
| _____/
|/
|
Now, in this flow, it turns out that the changes I made to one of the files in item1
also needs to be done in item2
(think of a utilities file to which I added a handy function).
So, based on the accepted answer for this question, I checked out the item2
branch and proceeded to pull the utilities file from the item1
branch as follows:
git checkout item2
git checkout item1 utilities.xyzzy
However, on checking git status
, it appears that this file has been put in the staging area whereas I thought it would make more sense to treat it as a freshly modified file:
pax> git status
On branch item2
Your branch is up-to-date with 'origin/item2'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: utilities.xyzzy
Why was this done this way? How can I, when pulling a file from a different branch into my current branch, get it to simply be a modified file that I will stage when ready?
@Thomson - Yes; in fact, that is the most common use of git checkout . When that happens, you switch HEAD to point to another branch or commit, and the entire staging area is changed to match that branch/commit.
You do this by checking out the master branch, and use git merge <branch name> . Git then merges the changes from the given branch into the checked out branch.
The git checkout command is used to update the state of the repository to a specific point in the projects history. When passed with a branch name, it lets you switch between branches. Internally, all the above command does is move HEAD to a different branch and update the working directory to match.
Even though the current working copy matches the one in branch2, the staged file does not, so a git checkout would lose that copy, and the git checkout is rejected. The underlying implementation mechanism for all of this is Git's index.
Make sure you do it on the right branch, though! A branch is a pointer to a commit. When you commit with a branch checked out, the branch advances to point to that new commit. When you check out a branch, you're checking out the commit it points to. (You can think of commits as snapshots of your work tree.)
Now switch back to the original branch by running the following command (change to master, if that's your initial branch). You can checkout a file from another branch using the syntax git checkout <branch_name> -- <path_to_file> We can also use the git show command to checkout a single file:
If the new branch contains edits that are different from the current branch for that particular changed file, then it will not allow you to switch branches until the change is committed or stashed. If the changed file is the same on both branches (that is, the committed version of that file), then you can switch freely.
Side note: when I read the original subject line "Why is file pulled from ..."
(now fixed), I thought you were referring to the git pull
script. It's worth emphasizing, I think, that you are referring specifically to git checkout
here, used in the form: git checkout branch path
.
Consulting the git checkout
documentation, we find this:
git checkout [-p|--patch] [<tree-ish>] [--] ...
When <paths> or
--patch
are given,git checkout
does not switch branches. It updates the named paths in the working tree from the index file or from a named <tree-ish> (most often a commit). In this case, the-b
and--track
options are meaningless and giving either of them results in an error. The <tree-ish> argument can be used to specify a specific tree-ish (i.e. commit, tag or tree) to update the index for the given paths before updating the working tree.
I put the crucial bit in boldface here: git first writes from the given "tree-ish" into the index (if not checking directly out of the index), then copies from the index to the work-tree. This is why the new file is staged. To undo the staging, you must use git reset
on the same path.
There is a way to get the file into the work-tree without copying it through the index, using git show
:
git show item1:utilities.xyzzy > utilities.xyzzy
The git show
command will pretty-print the specified object (in this case, that file) to standard output, and redirecting the output captures the file. Note however that this bypasses any smudge filter that would modify the file's contents on a normal checkout.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With