Reputation: 465
I have TEST
branch and then i have master
branch.
I have folder called DATA
with subfolders and files.
Now in my master i have
Now i only want to update TEST branch with new files from master branch so that everything else unchnaged for TEST branch but new files should be there.
I could do that easily with rsync
but just thinking if that could be done in git
Upvotes: 0
Views: 70
Reputation: 490178
You should be a bit careful with this as there are different answers to similar, but not exactly-the-same, questions. For instance suppose the commit history looks like this:
A - B - C <-- master
\
D - E <-- TEST
Here master
and TEST
start with a common commit, A
, and then diverge. Let's suppose that the common commit A
has these files (in directory DATA/
if you like, but I'll just name the files):
file_A1
file_A2
Suppose further that commit B
adds file_B1
but deletes file_A2
. Then, commit C
adds file_C1
and modifies file_A1
slightly.
This means if you git checkout master
you will get the three files (A1, B1, and C1) with the modified file_A1
contents.
Now suppose commit D
modifies file_A1
and adds file_B1
and file_D1
. Then commit E
removes file_B1
and adds nothing else.
This means if you git checkout TEST
you will get three files (A1, A2, and D1) with the modified file_A1
contents (which may be modified differently from the version in commit C
, or could be the same as the contents in commit C
).
When you ask about "files in TEST
that are not in master
", does file_A2
count? It's there if you git checkout TEST
; it's not there if you git checkout master
; but it was there in the common starting point, commit A
.
When you wonder about "files modified in both": clearly file_A1
was modified in both. But what if the change was identical in both, so that file_A1
has the same contents regardless of which branch is checked out. Is that "modified in both", or not?
What git needs you to do to answer such questions is to choose whether to compare two specific revisions, or to consider something more like a three-way merge (what you'd get if you attempted to merge TEST
and master
using their merge-base, revision A
, as a starting point).
git diff <options> master TEST
This will compare commit C
(what master
points-to, i.e., the "tip" of the master branch) vs commit E
(the tip of branch TEST
). So you'll compare the two file_A1
s, and see that commit E
has file_A2
and file_D1
and lacks file_B1
.
The <options>
part here may be empty, or may be as described below.
mergebase=$(git merge-base master TEST)
git diff <options> $mergebase master
git diff <options> $mergebase TEST
This does two separate diffs, of the merge-base (commit A
) against master
, and of the merge-base against TEST
.
The first diff will show you that on branch master
, the change from A
to C
is to modify file_A1
, delete file_A2
, add file_B1
, and add file_C1
.
This is the kind of operation git uses to figure out how to do a branch merge. In fact, there's a special syntax for running git diff
against the merge-base of two branches, against the tip of one of those two branches:
git diff <options> TEST...master # three dots
This does the same as the first diff (git diff <options> $mergebase master
). To compare the merge-base to the tip of branch TEST
:
git diff <options> master...TEST # again, three dots
As for <diff options>
, if you're not interested in the different contents of files, the obvious option to start with is --name-status
, which prints the names and status-es of the files, and --no-renames
, to turn off rename detection (unless you want rename detection, in which case, add -M
instead).
Files will show up as added, deleted, or modified (A
, D
, and M
status respectively) in terms of the change between the two trees you'd get if you checked out the commits chosen by the diff. There are more possibilities here though: T
occurs if a regular file is replaced with a symlink or vice versa (and more special cases with submodules); C
(plus a numeric similarity value) occurs if you add --find-copies-harder
and/or -C
options; and R
(plus a numeric value just like C
) occurs with rename detection. The C
and R
cases print not only the status and filename, but also the "origin file name".
You can add --diff-filter
to select only particular occurrences: --diff-filter=A
, for instance, will select only those files whose status is A
(added).
Upvotes: 2