how to merge specific files in git

前端 未结 4 760
傲寒
傲寒 2021-01-04 09:48

Suppose I have a project on MASTER branch with 100s of php files. To do a bug fixing in the project, i create a separate branch

git checkout -b bugfix


        
相关标签:
4条回答
  • 2021-01-04 10:24

    No, there doesn't exist a direct way. Though; you can select the files from branch you want to merge and overwrite them over existing ones in master branch. The commands in order shall be:

    git checkout master
    git show bugfix:login.php > login.php
    git show bugfix:register.php > register.php
    git add .
    git commit -m "Select login and register from branch/bugfix"
    

    Ok, the above method will "destroy" file history. There is an old discussion about the same in this mailing list.

    From a technical standpoint, the thing that makes history matter (and why "set of commits in date order" is useless) is because it gives us a COMMON ANCESTOR! And that is the only thing that matters.

    Now, what is fundamentally wrong with doing per-file history?

    Now, if you've followed this argument, you should go "Aaahh! Obvious!".

    Ignoring a whole lot of paragraphs; you'll find the workaround:

    git diff commit..othercommit filename | git-apply --index && git commit
    

    In your case, commit = hash of you HEAD/master branch; and othercommit = hash of bugfix branch.

    0 讨论(0)
  • 2021-01-04 10:27

    There is no way to record a partial merge in Git, all merges must merge the entire root trees of all the commits being merged.

    You can of course choose to resolve that merge by choosing the unchanged copy of one the files from one of the parents, but this is still a "full" merge and the changes in that file will be considered to have been merged when it comes to subsequent rebases or merges between the branches involved.

    0 讨论(0)
  • 2021-01-04 10:28

    You can simulate the behaviour you want but what happens with the changes you did on the third file?

    The changes on the third file remain in the commits on the branch but they will not be present in the merged commit, it's like the file was not modified on the branch at all.

    This is how you can do it:

    git checkout master
    git merge bugfix --no-commit
    

    The --no-commit option tells git to merge the files but stop before committing them. You can now inspect the files, change them, do whatever you want. In order to cancel the changes you did on index.php you can run:

    git checkout master -- index.php
    

    Running git status you can see that index.php does not appear as modified any more (neither in the index or in the working tree). You can now git commit and that's all.

    0 讨论(0)
  • 2021-01-04 10:47

    There are two approaches:


    Approach 01

    The following solution is adopted from a blog post

    It turned out that checkout can also be helpful in this matter. You can simply callout (checkout) those specific files from another branch:

    # switch to the branch you want to be your merge destination
    git checkout master
    
    # checkout specific files from specific branch (e.g bugfix)
    # format: git checkout <source branch> <file.1> <file.2> ... <file.N>
    git checkout bugfix login.php register.php
    
    # check the status
    git status
    
    # merge them in
    git commit -m "your merge comment"
    

    Approach 02

    This is an easy alternative approach, but it only works if you have one commit per file (meaning every time you have changed a file, you have made one commit and then have moved to the next file). In this case you can simply bring those specific commits to the other branch (in your case the master branch):

    # get which commit you want to take to the other branch (first 7 characters will do)
    git log
    
    # switch to the branch you want to be your merge destination
    git checkout master
    
    # bring specific commit to this branch (replace the 63344f2 with your own 7 character commit ID)
    git cherry-pick 63344f2
    
    0 讨论(0)
提交回复
热议问题