2

I am in branch B. After a bunch of commits, a few files are ready/needed by branch A, but many aren't ready/needed. I want to merge just those files, keeping proper git history. Later, when I really merge, I don't want any misleading trail about the origin of these changes -- they should properly reference the commits they came from, even though changes in other files that were part of those commits were not merged (yet). I guess that means dividing commits into pieces that do vs. don't concern these files.

All proposed solutions for this wind up losing the history of these changes and cause a big problem when I later want to merge B into A but some of B's changes are already there. I want a solution that avoids this.

In tortoise, I can look at the log for a single file and choose some older revision to revert to. So, in principle, I could make a new branch C, from B, and revert all the files I don't want to merge back to the point when B branched from A. Then I could merge C to A. That seems to properly track git history and lets me merge B into A without being surprised that some B changes are already there.

But it's painful to manually identify and revert 20 files, when I just want to merge 2. Why isn't this a common one-step operation? How does tortoise's revert work -- since it can operate on a single file, it must be sub-commit, which is the essential feature I'm looking for. Is it throwing away the fact that I am going from a newer revision to an older one, and making it look like I just made some manual changes that will then conflict with the eventual merge of B back to A?

user1441998
  • 459
  • 4
  • 14

2 Answers2

1

You are looking for cherry pick, a method to pick only certain commits from a branch to be merged.

To merge only certain files (when you don't want to merge a whole commit), you have multiple solutions indeed, i like to use the one well-expressed in this article, it's a pain in the arse anyway, bit it's the simpler i found to to that kind of things.

You can also split some commits and merge only the ones that contains the right files, and you can do like that other article says

WDRust
  • 3,663
  • 1
  • 19
  • 23
  • 2
    cherry pick is wrong -- it acts on whole commits and i want parts of commits. checkout is wrong cuz it doesn't maintain the merge/commit history. i don't want something that is a pain, and the "painless splitting" article is anything but, especially when there are a ton of commits involved. splitting commits would be part of a solution, but i want an automated way to figure out which commits and how to split them (ie, just those changes relevant to files i choose). – user1441998 Jun 07 '12 at 18:06
0

It's not a common one-step operation because Git is a content tracker, not a file tracker.

You can easily apply changes to specific files from branch B to branch A, just like Tortoise:

# raw file, no history
git checkout A
git checkout B myfile

or

# copy a set of history from someplace else
git checkout A
git cherry-pick commit-hash-1..commit-hash-2

but neither of those will preserve the history as merges from branch B. If that's what you're trying to do, depending on how the commits in branch B are organized, this might be better for you: Git: piecewise merge approach for major version changes?

Community
  • 1
  • 1
ellotheth
  • 4,333
  • 2
  • 17
  • 29
  • right, i want the history of commits/merges to accurately reflect that this work is coming from B. since it is technically possible using many steps in tortoise or doing commit splitting like M.Ang. referenced, i don't accept that git not being a file tracker precludes it from supporting this common usage need (several other SO questions request this, but they settle for losing history). – user1441998 Jun 07 '12 at 18:09
  • It's not precluded from doing the kind of file-specific merging you want to do, but since it *is* a content tracker, not a file tracker, the commits have to be set up with that in mind (see M.Ang's commit splitting, or the piecewise merging I linked). If you treat Git like a file-tracker, you won't get the behavior you want. – ellotheth Jun 07 '12 at 23:55
  • well, linus says in the post you linked that it could be made porcelain. i don't understand why he insists there is a content/file dichotomy. git could work just the way it does now, but consider commits to be made up of sub-commits with changes to only one file each, and then support file-based operations like i want to do. it's clear that people don't know at branch/commit-time what they will want to merge in the future, and this would solve that. git could be a content AND file tracker. – user1441998 Jun 08 '12 at 01:50
  • Your statement *it's clear that people don't know at branch/commit-time what they will want to merge in the future* suggests that you are describing a workflow problem, not a tool problem. More discussion: http://stackoverflow.com/questions/7323662/dvcs-partial-merge-git-hg-merge-tracking – ellotheth Jun 08 '12 at 05:18
  • so you think we are here to serve git, not vice versa? my proposal of dividing commits by file shows linus' claim that content-tracking and file-tracking are mutually exclusive is false, as well as his claim that file-tracking is fundamentally wrong (since it totally compatible with the architecture he claims is fundamentally right). so blaming the workflow that is clearly preferred by users is pure bluster. – user1441998 Jun 09 '12 at 01:00
  • 1
    If i can add my two cents, conceptually a commit is not "a bunch of modification to a bunch of files being added to the tracking system" but more "a feature/bugfix/stuff implemented in those files": in a /right/ git workflow, you should commit atomically for functionality/action on the sources (and often), so you won't ever want nor need to split commit for files when time to merge comes. If you had this wrong, you have to fix it in the ways that we discussed. You don't want to think at commits based on files, because you know, dependencies exists. Makes sense put that way? – WDRust Jun 09 '12 at 01:12
  • actually, this applies to likely every DVCS workflow, since your commits will affect only your local history and you can commit more "freely" than, say, with SVN or TFS. – WDRust Jun 09 '12 at 01:17
  • i agree the user shouldn't manage the commits file-by-file -- the dvcs should take the user's feature-based-commits and break them into file-by-file subcommits that are only exposed to the user when they decide they were wrong about the granularity of their commits and need to merge file-wise. what's an example where this wouldn't be perfect? ie, "dependencies" cause some kind of repository inconsistency? – user1441998 Jun 09 '12 at 04:31
  • *so you think we are here to serve git, not vice versa...something about bluster* Bluster? No, I think if your tool doesn't fit your process, you should switch tools. Git has a certain fundamental architecture and behaves in a certain way as a result. As has already been made clear, it doesn't do straightforward partial merges. If you don't like the behavior, fork it or use something else. Arguing that Git should behave differently without providing a solution in a medium not designed for extended discussion is unconstructive. – ellotheth Jun 09 '12 at 05:48
  • you said my workflow, not my tool, had a problem. i am proposing a design modification to support the workflow many users have requested and my question is "why doesn't git behave this way?" -- does it lead to some sort of inconsistency? why does linus think content and file tracking are fundamentally opposed, when you can just subdivide content changes into file changes? why has no one made it porcelain in the 5.5 years since linus said it was possible, even though it has been requested many times? – user1441998 Jun 09 '12 at 22:12