How can I Copy all the files, I have changed in last 10 days, from one branch, and place them into another git branch?
This locates all the files changed,
https://stackoverflow.com/a/8016702/14432516
git log --since="10 day ago" --author="John Smith" --name-only --pretty=format: | sort | uniq
Now, trying to utilize answer below, to specify a Subset of files to copy into another git branch. This answer takes All the files, not a specified group.
Example: Move/Copy 25 files from Git Branch A to Git Branch B, taking the files as is, Or merge (take source). Want all the files as in Branch A.
Looking for a quick automated way to conduct this for 100+ files.
Files aren't actually in branches. Files are in commits. Every commit has a full and complete copy of every file, or more precisely, every file that Git knew about at the time you (or whoever) made that commit.
Why this matters is that it makes the answer easy—or rather, mostly easy. We'll see more about this mostly part in a bit.
Given:
This locates all the files [I want to copy]:
git log arguments --name-only | sort -u
you can now simply copy those files from the last commit in the sequence of commits that git log
examined. Since the specified arguments
above didn't include any specific commit, Git started from the commit that was the HEAD
commit at that time, which would be the tip commit of the branch you had checked out at that time. For instance, let's say you had branch branch-A
out.
You might also want to, at this point, do: arguments="--since="10 day ago" --author="John Smith" --name-only --pretty=format:" files=$(git log $arguments | sort -u) echo $files
(The only reason for setting $arguments
first is to make all this fit on one line in this posting, and/or to let you run git log
like this more than once.)
[How do I get (those files) ready to be committed into a new commit I will make on
branch-B
?]
You'd next run:
git checkout branch-B
as usual. Then, as in the better answer to the question you linked, you would use:
git checkout branch-A -- $files
The $files
variable is set from the output from the git log --name-only | sort -u
command.
Where the mostly comes in is that $files
can have two problems:
Some of the file names might contain spaces. Shells such as bash
—the examples here are all sh / dash / bash compatible—treat spaces as breaking up arguments, which is why you can run git log --since=...
in the first place: each of those log
, --since
, --name-only
, and so on have to be passed to the Git command as separate arguments.
But suppose that you have a file named path/to/file with spaces.ext
. Then $files
contains path/to/file with spaces.ext
, which to bash, looks like you typed in path/to/file
as one argument, with
as a second argument, and spaces.ext
as a third argument.
If you are stuck with this situation, bash in particular has some ways to deal with it. Your best bet is to avoid spaces in file names in the first place, though.
It's possible that one of the activities on some file, that git log
showed you above, is that the file got deleted in that commit. The --name-only
option tells Git to show you only the names of files that had some change made, between the parent of the commit and the commit in question. If the change-made was "delete the file entirely", that file isn't in the new commit, and probably isn't in the final commit either, because it probably stayed deleted.
The right thing to do for such a file is generally to leave it deleted. So if you get an error about this file, just take it out of the $files
set: it's not in the commit at the tip of branch_A
so you can't copy it out of that commit, but you don't want to copy it out anyway. Just leave it deleted.
Note that instead of git checkout
above, you can use git restore
if your Git is 2.23 or later.1 This isn't any better than git checkout
, it's just a little clearer: the git checkout
command in Git versions predating 2.23 can do one of several jobs, and in Git 2.23, those jobs were subdivided into two separate commands: git switch
does about half of them, and git restore
does the other roughly-half of those jobs.
(Having split the command into two, the split-up commands were then made smarter and better. So in the current versions of Git, as time goes on, git switch
and git restore
put together can do more than git checkout
. The old git checkout
continues to exist so that if you are used to it, you can keep using it. If you need some of the new abilities, though, you must switch to the new commands.)
1When using git restore
, you'll want git restore --source=branch_A -iw -- $files
, rather than git checkout branch_A -- $files
. This is a little longer to type in, which can be annoying, but it has the same effect. The "smarter-ness" of git restore
is that you can select whether the files go into Git's index or not, and whether they go into your working tree or not, individually.