I read about git patch command, but all of the examples show how to get a patch for all not staged or cached files or even all files that some commit includes (from one commit till another). But suppose I have 10 not staged files and I need to create one proper patch just for 6 of them. How can I do this? And if there is a way to create such patch, how can I apply it?
Sorry if obvious.
Git patch from several (not all) unstaged files
524 Views Asked by z0lupka At
1
There are 1 best solutions below
Related Questions in GIT
- problem to push files on a repository git
- diff3 output in git conflict style, including mergeable hunks
- Git Not In Sync with Local Branch
- Setting up the version control of .dotfiles while the .config is connected to a forked repo
- How to fix overriding the main branch in Git?
- I can't add text to "Message" in VS Code when committing to Git
- How can i redirect pull request from main branch to another branch
- Xcode commits (possibly outside of any branch) disappeared, how to get them back?
- Git/TortoiseGit : how to apply ONLY the changes from ONE commit from branch A, to branch B?
- How can I reintroduce username an password on git using fedora?
- GIT SKIP EMPTY DIRECTORIES
- Git smudge run once per checkout or per commit?
- I can't find ~/.profile or ~/.bashrc in C:/Users/<user>/.ssh folder
- Set environment variable during push for GitHub Actions
- Android WebRTC compile
Related Questions in VERSION-CONTROL
- Setting up the version control of .dotfiles while the .config is connected to a forked repo
- How can i redirect pull request from main branch to another branch
- Visual Studio 2022 convert spaces to tabs on checkout and back to spaces on checkin
- Handle workspace/monorepo with different deployments
- P4 change ownership through command line
- gitignore for Unity VR project does not work
- Different SDK for specific build
- Sourcetree GUI : Why main branch is behind another branch? Is it normal?
- Strongly Connected Components Using Kosaraju Algorithm
- How to use git-credential-gopass with git send-email?
- Run Robot in Jenkinsfile does not fetch the correct test.robot file from Github
- Git Hub not showing my Organization's Repositories in Android Studio
- Sourcetree caches old branches that no longer exist on github. I do not want this
- How to retrieve Inference image location for my Sagemaker pytorch custom model for Model registry
- I have an error with my Material UI react-swipeable-views in TypeScript
Related Questions in DIFF
- diff3 output in git conflict style, including mergeable hunks
- Have the git gutter show the diff between the current HEAD and a selected commit/branch in Visual Studio Code
- git diff show changes where surrounding lines contain search term
- i want to compare and obtain new data of 2 files, but the place of the content changes lines
- Calculate Difference between columns where criteria in another column is met
- Git: clarifying doc for how "patch id" is computed and how it may relate to git diff:
- VSCode diff with textconv applies it only on the old file
- Git diff for a specific file using Simple Git in Node.js returns the entire diff
- How to enable heuristics in Myers linear space Diff algorithm?
- DOM diff algorithm with HTML streaming?
- Is it possible in VScode to diff two selections, two sections, two functions, etc of the same file?
- How to make diff prefer modification vs add/delete?
- How to use python get F5 configuration DIFF
- Is it possible to do "git diff --stat" with LFS?
- Can git-range-diff's results be presented in an external tool like we get with git-difftool?
Related Questions in GIT-DIFF
- diff3 output in git conflict style, including mergeable hunks
- Have the git gutter show the diff between the current HEAD and a selected commit/branch in Visual Studio Code
- Hex codes of Git standard colors
- How to change color in git diff
- Git: clarifying doc for how "patch id" is computed and how it may relate to git diff:
- Ignore blank spaces in code block with changes using git diff
- In git diff, how to exclude root level files
- What can I do, when the compare tool compares the wrong lines?
- Show git diff of the current line in vscode
- make git-diff ignore new lines
- Why does gitlab say i have tons of diffs even though i already merged the branch
- git diff --color-words separate removals and additions, get counts of each
- Checking out from github on Windows has strange CRLF effect
- Better way to diff changes that made to a specific branch without merged commits?
- What diff algorithm relies on finding the longest common prefix and suffix and cursing on the middle substring?
Related Questions in GIT-PATCH
- Git/TortoiseGit : how to apply ONLY the changes from ONE commit from branch A, to branch B?
- Git: clarifying doc for how "patch id" is computed and how it may relate to git diff:
- How to apply patches in git when multiple patches has some common changes?
- Gitlab - Commit hash doesn't match when create a commit through the Gitlab UI
- How to remove changes related to one file from patch
- git apply patch does not update commit id
- Error when trying to apply git diff, "No valid patches in input"
- How to create a git patch from the committed changes
- git apply is not respecting file renames using `git mv`
- Git apply patch to specific file outside of git repo
- how to see the file which would be committed
- Automerge after patch apply with conflics
- Is it possible to undo a `git add` and go to the exact same staging index as before?
- Create patch or diff file from git repository for target directory and apply it to another different git repository with different directory
- How to create a git patch with the parent SHA so it can serve as an archive?
Trending Questions
- UIImageView Frame Doesn't Reflect Constraints
- Is it possible to use adb commands to click on a view by finding its ID?
- How to create a new web character symbol recognizable by html/javascript?
- Why isn't my CSS3 animation smooth in Google Chrome (but very smooth on other browsers)?
- Heap Gives Page Fault
- Connect ffmpeg to Visual Studio 2008
- Both Object- and ValueAnimator jumps when Duration is set above API LvL 24
- How to avoid default initialization of objects in std::vector?
- second argument of the command line arguments in a format other than char** argv or char* argv[]
- How to improve efficiency of algorithm which generates next lexicographic permutation?
- Navigating to the another actvity app getting crash in android
- How to read the particular message format in android and store in sqlite database?
- Resetting inventory status after order is cancelled
- Efficiently compute powers of X in SSE/AVX
- Insert into an external database using ajax and php : POST 500 (Internal Server Error)
Popular # Hahtags
Popular Questions
- How do I undo the most recent local commits in Git?
- How can I remove a specific item from an array in JavaScript?
- How do I delete a Git branch locally and remotely?
- Find all files containing a specific text (string) on Linux?
- How do I revert a Git repository to a previous commit?
- How do I create an HTML button that acts like a link?
- How do I check out a remote Git branch?
- How do I force "git pull" to overwrite local files?
- How do I list all files of a directory?
- How to check whether a string contains a substring in JavaScript?
- How do I redirect to another webpage?
- How can I iterate over rows in a Pandas DataFrame?
- How do I convert a String to an int in Java?
- Does Python have a string 'contains' substring method?
- How do I check if a string contains a specific word?
You'd have to define the phrase proper patch first. What makes a patch proper? What makes one improper? For that matter, what's the difference between a patch and a diff? There is no one fixed answer, but see Difference between patch and diff files.
That said,
git diffproduces diffs, and is quite flexible. It's meant for human use, not for use by machines, so its output may or may not be what you want (especially since you did not define any of your terms). Thegit format-patchprogram is less flexible and meant more for use by machines: it produces output that can be digested easily bygit apply, which is meant to apply a single patch without committing it, orgit am, which is meant to apply a whole series of patches stored on your computer in "mailbox format", committing each one. (amhere is short for Apply Mailbox, more or less.)Because you haven't defined your terms, there's no single right answer to your question. If we assume you mean produce a file that
git applycan apply, we get one possible answer. If we assume you mean produce a mailbox-format patch thatgit amcan apply and commit, we get a different answer.The
git format-patchcommand will produce a mailbox formatted patch (or series of patches) from some commit or commits. So to use it, you must make a commit. You can simply commit those particular files you wish to have in your patch, on a new branch if you like. (See the long details below.)The
git diffprogram, or any of its more machine-oriented related commands (git diff-tree,git diff-files,git diff-index) will produce a human-readable diff. If it is not colorized, it will be suitable for use withgit apply. To use these, you need not make a commit.As LeGEC noted, you can use
git diffon specific files. Note that by default,git diff -- pathscompare the index copy of each specified path to the work-tree copy of the same path. This is probably what you want. If you have configuredgit diffto always produce colorized output, turn that off for the duration of the onegit diffoperation. Save the output somewhere:or:
if you need to disable colorization.
Long: about commits
If the above suffices, there's no need to read the rest of this.
If your definition of proper patch means one that
git amcan turn into a commit, you will need to make a new commit. This is where knowing what staged vs not staged, and how branch names and commits all work, becomes very important.Git is really, at its heart, all about commits. Branches—or more specifically, branch names—are useful, especially if you are a human, but they're not really what Git is about. Git is all about the commits.
Every commit is numbered, but the numbers are not simple sequential counts. We can't find commit #1, then commit #2, and so on. Instead, each commit gets a unique hash ID. This thing looks random, but in fact is entirely non-random, and is carefully computed so that every Git will number a 100%-identical, bit-for-bit-the-same commit the same way. That way, every Git everywhere will agree that this commit gets this hash ID, and no other commit gets this hash ID.
What goes into a commit comes in two parts: the data, and the metadata:
The data in a commit is pretty simple: it's a full snapshot of every file that Git knows about.
This obviously makes Git repositories grow enormously fat, since every commit stores every file. But they don't (grow enormously fat). The reason is that the files are stored in a special, read-only, Git-only, compressed and de-duplicated format. If you make a thousand commits, each with 1000 files, but re-use 999 of the 1000 files each time, then all thousand commits share 999 files with other commits.
(There is more to it than this, but the de-duplication is the first step, and a very big one.)
The metadata in a commit is information about the commit. This is where Git stores the name and email address of the person who made the commit, for instance. In this metadata, Git stores one particular set of information that Git needs for itself, though. Every commit stores the commit number—the hash ID—of its parent commit. This is how history exists in a repository.
Since the files in the commits are read-only—and Git-only, frozen-for-all-time, compressed into this special freeze-dried format that only Git itself can use—the files you work with have to be extracted from commits. This is what
git checkout(or, since Git 2.23,git switch) does. You pick a commit and tell Git: Extract all the files from this commit, so that I can see them and work with / on them.Since each commit remembers its previous commit, all you need to do, to use Git, is have Git remember for you the unique hash ID of the last commit. This is where branch names come in. A branch name simply holds the hash ID of the last commit that is to be treated as part of that branch.
This means we can draw a branch like this:
The name
masterholds the actual hash ID of the last commit, which at this point is hash IDH. That commit holds a snapshot of all of your files, and also holds the hash ID of earlier commitG.Git can look up any commit—any internal object, really—by its hash ID, so Git can look up commit
H, extract all of its files, and let you work on it. Or, Git can look up commitH, find its parent hash IDG, and look up commitG. Git can then extractG's files, or look up its parent hash IDF. This is the first of the big secrets of Git.Commits, your work-tree, and the index
Given the above—read-only commits, and read/write files—we have already seen that Git must extract a commit into an area where you can see and work on your files. This area is your working tree or work-tree. So there are two copies of each file of interest: the one in the current commit, which is frozen for all time, and the one in your work-tree, which you can use. It's pretty straightforward, with one twist: you can create files in this area that Git doesn't know about.
The really tricky part here, though, is how Git makes a new commit, and what files Git does know about. You might think that Git would just keep a list of file names, for instance, and use your work-tree files to make new commits ... but it doesn't.
Instead, Git keeps a third copy—well, a de-duplicated copy, in the freeze-dried format—in an in-between place. Between the current commit and your work-tree, Git has this other "copy" (already de-duplicated, so not exactly a copy) of each file that Git took out of the commit at checkout time.
These in-between "copies" of each file are in what Git calls, variously, the index, or the staging area, or (rarely these days) the cache. Note that these copies are ready to go into a new commit, as they're already in the Git-only, freeze-dried format. Unlike the copies in the commits themselves, they can be replaced, though.
This is what
git addis all about. Thegit addcommand means Make the index copy of some file(s) match the work-tree copy. If you have changed a file in your work-tree, you must tell Git to copy the updated file back into Git's index.This is what a staged file is. At all times, Git's index has copies of each file that Git knows about. If it's in the index, it's ready to be committed—but maybe it's the same as the file in the current commit! If so, it's already de-duplicated, and Git can easily tell that it's the same.
If the index copy of a file is different from the current commit copy, or is entirely new, then what will go into the next commit is different from what is in the current commit. Git calls that staged. If the index copy is the same as the committed copy, though, Git says nothing at all.
Meanwhile, the index copy of a file might match the work-tree copy, or not. If the index copy does match the work-tree file, Git doesn't say anything about it. If not, Git says that the file is unstaged.
This means a file can be both staged for commit and not staged for commit, at the same time! If the committed copy (which can't be changed) doesn't match the index copy, and the index copy doesn't match the work-tree copy, you have a file that is both staged for commit and not staged for commit. You can get this state by doing:
When you run
git commit, what Git does is to make a new commit from whatever is in Git's index at that time. So if you have ten unstaged files right now, and yougit addsix of them and then rungit commit, you get a new commit in which:git commit), butNow that you have made the new commit, the new commit is the current commit. You made it from the files that are in the index, so all files in the new, now-current commit match all the files that are in the index. No files are "staged for commit", but the four files you didn't
git addare still there in your work-tree, still different from the corresponding four files in the index and those four files in the current commit. So these four files are still "not staged for commit".If you like, you can now
git addthese four files to copy the work-tree versions back into Git's index, and thengit committhe result. You now have two new commits that you did not have before. The last one matches your work-tree, so that the current commit, Git's index, and your work-tree all match: no files are staged and no files are unstaged.More about branch names
Note that each time you do make a new commit, Git has to update the current branch name. Suppose you're on your
masterbranch initially, like this:Now you create a new branch name, such as
feature. This new name also identifies commitH. We'll add the nameHEAD, in all capital letters, to one of the branch names to show which one we're using:Now we'll
git addsome file(s) and make a new commit. It will get a new random-looking hash ID; we'll just call thisI:The trick is that Git now writes
I's hash ID into the namefeature—the oneHEADis attached-to—so that the name points toInow:If we add some more files and
git commitagain, we get another new commitJ:Note that each commit has a full snapshot of every file, as it appeared in Git's index at the time you ran
git commit. When you usegit format-patchto turn a commit into a patch, Git:HforI);I);Since this is a commit-able patch, Git adds a header to it giving the name and email address of the person who made the commit, an appropriate date-and-time stamp, and the log message in which whoever made the commit explains why they made that commit. The patch itself comes after this header.