How can I selectively merge or pick changes from another branch in Git?

前端 未结 25 1552
慢半拍i
慢半拍i 2020-11-22 02:53

I\'m using Git on a new project that has two parallel -- but currently experimental -- development branches:

  • master: import of existing codebase pl
相关标签:
25条回答
  • The easiest way is to set your repository to the branch you want to merge with, and then run

    git checkout [branch with file] [path to file you would like to merge]
    

    If you run

    git status
    

    you will see the file already staged...

    Then run

    git commit -m "Merge changes on '[branch]' to [file]"
    

    Simple.

    0 讨论(0)
  • 2020-11-22 03:25

    Here's how you can get history to follow just a couple of files from another branch with a minimum of fuss, even if a more "simple" merge would have brought over a lot more changes that you don't want.

    First, you'll take the unusual step of declaring in advance that what you're about to commit is a merge, without Git doing anything at all to the files in your working directory:

    git merge --no-ff --no-commit -s ours branchname1
    

    ... where "branchname" is whatever you claim to be merging from. If you were to commit right away, it would make no changes, but it would still show ancestry from the other branch. You can add more branches, tags, etc. to the command line if you need to, as well. At this point though, there are no changes to commit, so get the files from the other revisions, next.

    git checkout branchname1 -- file1 file2 etc.
    

    If you were merging from more than one other branch, repeat as needed.

    git checkout branchname2 -- file3 file4 etc.
    

    Now the files from the other branch are in the index, ready to be committed, with history.

    git commit
    

    And you'll have a lot of explaining to do in that commit message.

    Please note though, in case it wasn't clear, that this is a messed up thing to do. It is not in the spirit of what a "branch" is for, and cherry-pick is a more honest way to do what you'd be doing, here. If you wanted to do another "merge" for other files on the same branch that you didn't bring over last time, it will stop you with an "already up to date" message. It's a symptom of not branching when we should have, in that the "from" branch should be more than one different branch.

    0 讨论(0)
  • 2020-11-22 03:25

    I found this post to contain the simplest answer. Merely do:

    git checkout <branch from which you want files> <file paths>
    

    Example

    Pulling .gitignore file from branchB into current branch:

    git checkout branchB .gitignore
    

    See the post for more information.

    0 讨论(0)
  • 2020-11-22 03:25

    I had the exact same problem as mentioned by you above. But I found this Git blog clearer in explaining the answer.

    Command from the above link:

    # You are in the branch you want to merge to
    git checkout <branch_you_want_to_merge_from> <file_paths...>
    
    0 讨论(0)
  • 2020-11-22 03:26

    1800 INFORMATION's answer is completely correct. As someone new to Git, though, "use git cherry-pick" wasn't enough for me to figure this out without a bit more digging on the Internet, so I thought I'd post a more detailed guide in case anyone else is in a similar boat.

    My use case was wanting to selectively pull changes from someone else's GitHub branch into my own. If you already have a local branch with the changes, you only need to do steps 2 and 5-7.

    1. Create (if not created) a local branch with the changes you want to bring in.

      $ git branch mybranch <base branch>

    2. Switch into it.

      $ git checkout mybranch

    3. Pull down the changes you want from the other person's account. If you haven't already, you'll want to add them as a remote.

      $ git remote add repos-w-changes <git url>

    4. Pull down everything from their branch.

      $ git pull repos-w-changes branch-i-want

    5. View the commit logs to see which changes you want:

      $ git log

    6. Switch back to the branch you want to pull the changes into.

      $ git checkout originalbranch

    7. Cherry pick your commits, one by one, with the hashes.

      $ git cherry-pick -x hash-of-commit

    0 讨论(0)
  • While some of these answers are pretty good, I feel like none actually answered the OP's original constraint: selecting particular files from particular branches. This solution does that, but it may be tedious if there are many files.

    Let’s say you have the master, exp1, and exp2 branches. You want to merge one file from each of the experimental branches into master. I would do something like this:

    git checkout master
    git checkout exp1 path/to/file_a
    git checkout exp2 path/to/file_b
    
    # Save these files as a stash
    git stash
    
    # Merge stash with master
    git merge stash
    

    This will give you in-file diffs for each of the files you want. Nothing more. Nothing less. It's useful you have radically different file changes between versions --in my case, changing an application from Ruby on Rails 2 to Ruby on Rails 3.

    This will merge files, but it does a smart merge. I wasn't able to figure out how to use this method to get in-file diff information (maybe it still will for extreme differences. Annoying small things like whitespace get merged back in unless you use the -s recursive -X ignore-all-space option)

    0 讨论(0)
提交回复
热议问题