Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
622 views
in Technique[技术] by (71.8m points)

Git ignores deleted file on merge

I have two repositories. From time to time, I want to merge the content of other into main. However the merge ignores deleted files. Let me explain it through an example:

mkdir -p test/main test/other

cd test/other/
git init
touch one two three
git add .
git commit -m "Add one, two and three."

cd ../main/
git init
touch four
git add .
git commit -m "Add four."

Add other to main as remote.

git remote add other ../other/
git fetch other

Merge its content.

git merge --squash other/master
git commit -m "Merge other."

It adds the files correctly. Now, remove a file in other.

cd ../other/
git rm two
git commit -m "Remove two."

Merge changes into main.

cd ../main/
git fetch other
git merge --squash other/master

After the merge git status says:

# On branch master
nothing to commit (working directory clean)

I would expect the merge to delete two, as it was deleted in other. What am I doing wrong?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The issue here is your use of squash commits.

When you do a merge --squash, you abandon all of the history of a branch. You haven't really "merged the branch" - you've just applied a condensed representation of its history. So if you do a later merge --squash, git will reapply all the commits in the branch's history (since the two branches have no common ancestor).

When you perform the first merge --squash, you create a commit on main which contains "Create one, two, and three". So the history of main is first "create four", then "create one, two, and three".

When you do the second merge --squash, you add a commit which consists of (in effect) "Create one, two, and three" plus "Remove two". The net of those two commits together (squashed!) is "Create one and three". So git auto-merges the "Create one and three" commit with your current repo state - leaving you with four files present. The content merge succeeds automatically because the files "one" and "three" are identical on both sides.

You should use "real" merges or cherry-picking instead of squashing if you want to keep a repo up-to-date with a remote. A merge --squash is not the same thing as "play through all the new commits in a remote repository and integrate them here".


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...