For one reason or another, I occasionally find myself in a place where I want to copy off all my modified files in my local git repository and start over. This is usually due to painful merges where I just want a fresh start. This is the one-liner you can use to do just that:
git status --porcelain=v1 | awk {'print $2'} | xargs -I {} cp -r {} ../dir_with_changed_files
Let's break down each part of this line in detail.
git status --porcelain=v1
You may be familiar with git status
, adding the --porcelain=v1
flag just changes the output from this:
to this:
awk {'print $2'}
This awk command will print the 2nd column of standard out (i.e. what is printed on the screen). In our case, this will print out the column with the file names from the previous git status --porcelain=v1
command.
xargs -I {} cp -r {} ../dir_with_changed_files
This portion of the command utilizes the xargs tool which allows iteration over things coming from standard input. In this case, standard input for the xargs
command is the standard output from the previous awk
command. Which take the list of files and copies it to the ../dir_with_changed_files
directory.
Top comments (8)
Interesting. I made up a similar command that uses 'tar' command to create a .tar(.zip) file, but in a dirty way. I would check that porcelain flag, when i can
Yeah, I feel like a lot of people come up with different solutions for this same problem. What is your command? It's always good to see different options.
As I see now, "status -s" is similar to "status --porcelain".
My comand does not skip first column, so it will try add files "??" or "M" to the new .tar file, it will fail (and show a warning/error) as it will not find them, but it will continue with the other arguments.
Basically it is
tar cvf newFile.tar [list of file names separated with spaces]
DISCLAIMER TO EVERYBODY: my command is dirty and not tested. I dont take any responsability of anyone using it. Learn "tar cvf" and `` before using it :-)
Thanks for sharing, Liz, maybe i will try yours and/or the awk comand. Thanks
Ah I see you. Yes, you can do something similar like this:
git status -s | awk {'print $2'} | xargs -I {} tar -cvf newfile.tar {}
Thanks for sharing!
Pretty interesting!!
tried your approach, here the files which are renamed cannot be copied to the destination folder
Hmmm...this should work for renamed files. There may be an error for the original file that no longer exists, but that should not stop the command from working. What are you observing?
True, when you rename the file, eventually file does not exist hence the renamed file is not considered.
I added a small if-else(just for renamed files) in the above statement to make it work for my use case.
git status --porcelain=v1 | awk {' if ($1 == "R") print $4 ; else print $2'} | xargs -I {} cp -r {} modified_files/
Ah I see. You are actually doing a
git mv
to rename your files. Yes, you are right, in that case your solution is perfect! Thanks for sharing!