extract all files changed in a git commit - windows

I need to make a patch for someone (they are not using git) - a zip of the files changed by a commit.
I thought something like
git archive --format=zip commitguid > myfiles.zip
but this extracts the entire thing, not just the changed files. Is there any way to do this?
And to make it more complicated - is there any way of doing this with multiple commits (yes I should have branched before making the changes but that's hindsight)
EDIT
Based on #Amber solution below I can do this in 2 steps in Git Bash for windows with 7Zip installed in c:\data\progs.
git diff --name-only a-sha b-sha > tmp.txt
/C/data/progs/7za.exe a myzip.zip #tmp.txt

git diff --name-only <oldsha> <newsha> | zip dest.zip -#
filling in the proper SHAs/refs. For instance, to create a zip of only the files that changed between the master and feature branches:
git diff --name-only master feature | zip dest.zip -#

See also git help format-patch. It produces a diff patch of all changes in a commit along with commit author, date, message, and some nice diff stats. You could zip and send that.

I found this solution to the question (on github-gist, from user rmkpatchaa).
It doesn't require any external tools and is a one line command in a windows Git Bash window:
git archive --output=changes.zip HEAD $(git diff --name-only SHA1 SHA2 --diff-filter=ACMRTUXB)
It creates a standard zip archive with only the files changed between the two commits, no extra git stuff or anything, and doesn't require any extra tool on the receiving side.

Related

How to check file/directory changes of a multi directory git repository between two git commits?

How to check file/directory changes of a multi directory git repository between two git commits?
In linux/bash we need to findout changes to a directory of multi-directory(e-store) git repository, say it has inventory-dir, order-dir, purchase-dir etc.., directories.
So basically after we do git pull we want to know in which folderes/directories files changes were made between present changes & last commit, and based on that output take an appropriate call.
We tried to use below git commands, but not sure that's the right way to proceed.
git diff inventory-dir
git log --name-status -2 inventory-dir
You might be looking for
git diff #^1
but to reduce the result to a tractable list of just file names you could add
--stat
or
--compact-summary
or merely
--name-only
Of those, my favorite is --compact-summary — it's tremendously informative while confining the output to one line per file. So then if you have a top-level directory myDirectory to which you wish to confine your attention, you would say
git diff --compact-summary #^1 -- myDirectory

git - How to get files changed with specific commitid without update to head?

I want to make a automated test system. Users upload or change their script, when they push file to git, system will get the commit action, and know the commit id, like 3c6a88d527ccaefabf98d00f47f04789f01e2830, and boot a docker to run changed script.
at first, git clone all file to a directory, after that get what files is changed by order:
git diff-tree --no-commit-id --name-only -r <id>
After a long time, there will be a lot of scripts in the repository, I don't want to pull all the scripts to the local directory every time I test.Is there any command to pull only part of the files I want?
# Shows commit logs and diff output
git whatchanged <sha-1>
Using diff-tree (as you figured out)
# Fetch out changes (no need to checkout branches)
git fetch --all --prune
# Now print out the changes
git diff-tree --no-commit-id --name-only -r <id>

having trouble with a git sparse checkout (folder)

here is my git server tree:
----a/
|--b/
|--c/
|--d/
|--e/
|--f/
|--g.txt
|--h.readme
here is my git version tree
---------------->master
|---->myBranch [files are up to date here]
here is my jenkins server tree
-----A/
|--B/
|--C/
I am trying to checkout the content of repository "e" in repository "B"
I just need the last version of the current branch i'm working on, and I don't want to commit, just to get some up-to-date read-only scripts to run, so depth 1 is okay I guess.
Anyway, The problem I'm facing is that I'm able to to a sparse checkout with
#############################
##### 1/ configuring local folder
#############################
git init
git config core.sparseCheckout true
#an empty repository with the remote is created:
git remote add -f origin ssh://guillaumedg#domain.com:port/myProjects/thisProject.git
#add repository "e" to be checked out:
echo e/*> .git/info/sparse-checkout
#############################
##### 2/ fetching/updating files
#############################
git fetch
git checkout myBranch
I know I'm close, but what I get is this:
-----A/
|--B/
| |----a/
| |--d/
| |--e/
| |--f/
| |--g.txt
| |--h.readme
|--C/
not this (which is what I want)
-----A/
|--B/
| |--f/
| |--g.txt
| |--h.readme
|--C/
any hints?
by the way I tried different ways of using "depth 1" for "step 2" with no success:
git fetch --depth 1 $(url) $(branch)
git checkout $(branch)
--> error: pathspec 'myBranch' did not match any file(s) known to git.
git fetch --depth 1 $(url) $(branch)
git checkout
--> fatal: You are on a branch yet to be born
git fetch --depth 1 $(url) $(branch)
git checkout -b $(branch)
fatal: A branch named 'myBranch' already exists.
git fetch
git checkout $(branch)
--> works as describe above
Git doesn't store directories, only files. So, given your drawing here:
----a/
|--b/
|--c/
|--d/
|--e/
|--f/
|--g.txt
|--h.readme
the repository has some commits that have files named:
a/d/e/f/g.txt
and:
a/d/e/h.readme
You can direct your Git to check out these specific files, using either command line options or the sparse checkout option you're attempting to use. Their names will still be a/d/e/f/g.txt and a/d/e/h.readme.
Your computer probably requires that these names be created by making a directory (or folders) named a, then making one named d in a, and so on. Git will do that. You cannot make Git use any other name for these files if you're going to use git checkout to extract them.1
So, that leaves you with the option of not using git checkout to get these files. You could get the commit (as you are doing already), then use git show on individual path names, for instance. The standard output of git show will show the file's contents; you can redirect this to a file name of your choice.
Since you don't want the whole repository, consider using git archive to turn one commit into an archive. Since you don't want the whole commit either, consider adding to this git archive command the name(s) of the file(s) that you want archived.2 You may then have an un-archiver that can skip the a/d/ part of the path names of each archived file. For instance, GNU tar has --strip-components.
1I think it would be nice to be able to remap stored file names to in-file-system names, for many reasons, including the case-folding issues and cheeky Linux programmers creating files named CON and LPT. :-) But Git can't, at least not today.
2This isn't required, and if you're downloading this kind of git archive from a hosting server such as GitHub, you may not be able to do that. But if you can do that, you'll save some amount of space and transfer time. Given your ssh://user#host URL, you can probably run ssh user#host "cd path/to/repo; git archive ..." and pipe the result to a local tar -xf -, for instance.

How to show all the files that have been changed?

I am working on a feature branch that branched off a develop branch. Now that I am ready to do a PR I just want to check which files have been changed. What git command will list all the files changed against the develop branch?
Git's diff command with the --stat option will show you a list of changed files without the detailed contents.
Use it like git diff --stat origin/develop feature_branch
If you want really basic results then you can instead use the --name-only option to just see the filenames and nothing else.
If you just want to see the file names, you can do
git diff --name-only develop
git diff develop
Often the PR tool will show you the differences too.
For example if Microsoft's Dev Ops (previously known as VSTS) when creating a pull request you can see the changes (and commits) at the bottom.

How to print all the staged file names using ruby git pre-commit hook?

I just started playing around with git hooks using Ruby(as am more comfortable with ruby).
Can anyone tell me how to print all the staged file names? and can anyone tell me or give me a good resource where I can understand how will git search through the staged files and search for a particular text?
One possible command is (from "Git pre-commit hook : changed/added files"):
git diff --cached --name-only --diff-filter=ACM
That is what I recommended for that other ruby pre-commit hook"
And you could use it with "jish/pre-commit".

Resources