Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I use git merge --squash with --no-ff?

I'm trying to use the git merge --squash with the --no-ff parameter, but git does not allow. Someone have any sugestion to help me?

I can't use fast forward merge and I need to use the --squash parameter to group a lot of commits that were made in another branch.

Thanks!

like image 981
Guilherme Chiara Avatar asked Jan 14 '13 15:01

Guilherme Chiara


People also ask

What is -- no FF in git merge?

The Git merge --no-ff command merges the specified branch into the command in the current branch and ensures performing a merge commit even when it is a fast-forward merge. It helps in record-keeping of all performed merge commands in the concerning git repo.

How do I force merge squash in GitHub?

On GitHub.com, navigate to the main page of the repository. Under your repository name, click Settings. Under "Pull Requests", select Allow squash merging. This allows contributors to merge a pull request by squashing all commits into a single commit.

How do you force merge squash?

Enabling Commit Squashing by Default To enable commit squashing as the default option in your repository: Navigate to your chosen repository and open the Settings sub-tab. Open the General Settings page. Check the box for Squash commits on merge default enabled.

Does git merge squash by default?

Explanation. You can't make Git do a squash "merge" by default for all branches, but you can make it do a squash "merge" by default for some branches.


2 Answers

It probably doesn't let you because such a command wouldn't make sense.

The documentation for --squash says (emphasis mine):

--squash
Produce the working tree and index state as if a real merge happened (except for the merge information), but do not actually make a commit or move the HEAD, nor record GIT_DIR/MERGE_HEAD to cause the next git commit command to create a merge commit. This allows you to create a single commit on top of the current branch whose effect is the same as merging another branch (or more in case of an octopus).

The --no-ff flag does:

Create a merge commit even when the merge resolves as a fast-forward.

You are essentially asking git to make a commit and NOT make a commit at the same time.

If you want to preserve all of the history of your branch, you should use the --no-ff flag. Commit d is a merge commit that has two parents, a and c.

a ------ d -- ....  \      /   b -- c   

If you want all of the commits on that branch to be treated as a single unit of work, then use --squash. Commit d is a regular commit that contains all of the changes from commits b and c but has only one parent, a.

a ---- d -- ....  \         b -- c   
like image 128
Roman Avatar answered Oct 04 '22 02:10

Roman


What does --squash do? - it squashes all the commits together, creates your index state such that you can commit all the changes from the branch as a single commit. The change in your code will be like you merged the branch, but your history will be like you made one huge commit.

What does --no-ff do? - it says, even if the branch can be fast-forwarded, do treat it as a merge and create a merge commit.

As such, --squash is about getting a history without a trace of merge. --no-ff is about forcing a history with merge, even when it is being forwarded. As such, they are mutually exclusive and cannot be used together.

I think the question arises from a misunderstanding of fast-forward. It is not a merge; it is just about forwarding a branch directly to another commit from the merged branch because the commits were made directly on the commits in the former branch. No fast forward stops this behaviour and forces a merge commit on top. When you are squashing, it doesn't matter if you are asking it to not fast-forward. It would be the same either way.

like image 26
manojlds Avatar answered Oct 04 '22 01:10

manojlds