Git merge squash repeatedly

后端 未结 5 2119
暗喜
暗喜 2020-12-04 09:23

I\'m trying to have two branches with binary files in git - one \"development\" and one \"stable\". The development branch can have several changes of these files before I w

相关标签:
5条回答
  • 2020-12-04 09:27

    Starting with

          X stable
         /                   
    a---b---c---d---e---f---g development
    

    You can use the following steps to copy the last commit from your development branch to your stable branch:

    git checkout development@{0}  # get working tree from "development", detach HEAD
    git reset --soft stable  # reposition detached HEAD on "stable"
    git commit  # enter the appropriate commit message
    git branch temp  # create a temporary branch "temp" at HEAD
    git checkout temp  # get on the new temporary branch
    git branch -M stable  # rename "temp" to "stable"
    

    so you end up with:

          X-------------------G stable
         /                   
    a---b---c---d---e---f---g development
    

    If you continue work on "development", e.g.,

          X-------------------G stable
         /                   
    a---b---c---d---e---f---g---h---i---j development
    

    you can repeat the same git commands as above and you will end up with:

          X-------------------G-----------J stable
         /                   
    a---b---c---d---e---f---g---h---i---j development
    
    0 讨论(0)
  • 2020-12-04 09:33

    This isn't the right place to use merge --squash. One good place to use it is in a throwaway topic branch, which you're going to merge into your main branch and then get rid of. All the development done in the topic branch is shown as one commit in the main branch. In your situation, you should merge from the development branch normally, and then use git-rebase --interactive to squash the commits you want.

    Is it possible to somehow record the merge, without producing a "merge commit" with two parents?

    If I understand the question correctly, no. Absolutely not.

    Is it possible to tell git to merge only a certain "range" of revisions, like in SVN?

    Yes. git merge [commit hash]

    Or, is it possible to do a normal merge without having to download all refs from the other branch when pulling?

    See answer to previous question.

    Or should I provide a custom merge driver for the files in question, that simply renames "their" version to "our", thereby resolving the conflicts? I'm still afraid that --squash will always try to merge the whole history, up to the common parent, solving only half of my problem.

    No! Just don't use git merge --squash. This isn't the right place to use it!

    0 讨论(0)
  • 2020-12-04 09:33

    you could use git rebase -i (interactive mode) to sqash all your changes, just change the lines to m or meld (update: for newer Git releases type s or squash)

    you will than have a single commit which you can merge. if you want every step of yours reserved, you have to create another branch on your hacking branch before doing the rebase, this can be done with git branch small-dirty-changes-i-don’t-want-anybody-to-see

    all this has to be done before attempting to merge; step by step:

    # on branch "hacking": hack commit hack commit hack commit
    
    # create a reference to your history
    $ git branch dirty-history
    
    # sqash your commits by setting all lines to "meld"
    $ git rebase -i
    
    # checkout master or the branch you want to merge to
    $ git checkout master
    
    # merge your squashed commit
    $ git merge hacking
    # or: $ git pull hacking
    
    0 讨论(0)
  • 2020-12-04 09:42

    The top voted answer effectively diffs the stable and the development branches and applies all changes missing in the stable as one commit. There is an alternative way to do this:

    $ git checkout stable 
    $ git diff stable development | git apply --index -   
    $ git commit
    

    Before you commit, you can review the staged files. If you want to abort the process after you applied the diff, you can just use basic commands to remove changes from index and working directory.

    $ git reset --hard
    

    You can repeat the process any number of times, since you are effectively just diff-ing the tips of both the branches each time you need to merge.

    Note that there is assumption here that applies to the other answer as well: there are no commits in the stable branch other than the ones that came from the development branch. If the same line were changed independently in both branches, unlike a regular merge, this approach would not give you a conflict. Instead, it would just override the changes in the stable branch with the ones in development.

    If you are concerned about this, each time you commit on stable, you can put the merged development commit hash range in the commit message. That way, you have some record, if you ever need to backtrack.

    0 讨论(0)
  • 2020-12-04 09:44

    I'm new to git, but it seems like --squash is what you want, you just need to handle the branch differently.

    $ git merge --squash development
    $ git branch -d development
    $ git checkout -b development
    # continue work on development branch
    

    This would essentially truncate the history of the development branch, and the next merge would only be what you wanted. Looking at the man page it seems like git branch -f development might do the same thing as deleting and recreating the branch.

    As I said, I'm pretty new to git, so I'd love some feedback on this idea.

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