Skip to content

Commit c5a8f1e

Browse files
committed
Merge branch 'bc/faq-misc'
More FAQ entries. * bc/faq-misc: docs: explain how to deal with files that are always modified docs: explain why reverts are not always applied on merge docs: explain why squash merges are broken with long-running branches
2 parents 9bc233a + 087c616 commit c5a8f1e

File tree

1 file changed

+86
-0
lines changed

1 file changed

+86
-0
lines changed

Documentation/gitfaq.txt

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,59 @@ How do I know if I want to do a fetch or a pull?::
241241
ignore the upstream changes. A pull consists of a fetch followed
242242
immediately by either a merge or rebase. See linkgit:git-pull[1].
243243

244+
Merging and Rebasing
245+
--------------------
246+
247+
[[long-running-squash-merge]]
248+
What kinds of problems can occur when merging long-lived branches with squash merges?::
249+
In general, there are a variety of problems that can occur when using squash
250+
merges to merge two branches multiple times. These can include seeing extra
251+
commits in `git log` output, with a GUI, or when using the `...` notation to
252+
express a range, as well as the possibility of needing to re-resolve conflicts
253+
again and again.
254+
+
255+
When Git does a normal merge between two branches, it considers exactly three
256+
points: the two branches and a third commit, called the _merge base_, which is
257+
usually the common ancestor of the commits. The result of the merge is the sum
258+
of the changes between the merge base and each head. When you merge two
259+
branches with a regular merge commit, this results in a new commit which will
260+
end up as a merge base when they're merged again, because there is now a new
261+
common ancestor. Git doesn't have to consider changes that occurred before the
262+
merge base, so you don't have to re-resolve any conflicts you resolved before.
263+
+
264+
When you perform a squash merge, a merge commit isn't created; instead, the
265+
changes from one side are applied as a regular commit to the other side. This
266+
means that the merge base for these branches won't have changed, and so when Git
267+
goes to perform its next merge, it considers all of the changes that it
268+
considered the last time plus the new changes. That means any conflicts may
269+
need to be re-resolved. Similarly, anything using the `...` notation in `git
270+
diff`, `git log`, or a GUI will result in showing all of the changes since the
271+
original merge base.
272+
+
273+
As a consequence, if you want to merge two long-lived branches repeatedly, it's
274+
best to always use a regular merge commit.
275+
276+
[[merge-two-revert-one]]
277+
If I make a change on two branches but revert it on one, why does the merge of those branches include the change?::
278+
By default, when Git does a merge, it uses a strategy called the recursive
279+
strategy, which does a fancy three-way merge. In such a case, when Git
280+
performs the merge, it considers exactly three points: the two heads and a
281+
third point, called the _merge base_, which is usually the common ancestor of
282+
those commits. Git does not consider the history or the individual commits
283+
that have happened on those branches at all.
284+
+
285+
As a result, if both sides have a change and one side has reverted that change,
286+
the result is to include the change. This is because the code has changed on
287+
one side and there is no net change on the other, and in this scenario, Git
288+
adopts the change.
289+
+
290+
If this is a problem for you, you can do a rebase instead, rebasing the branch
291+
with the revert onto the other branch. A rebase in this scenario will revert
292+
the change, because a rebase applies each individual commit, including the
293+
revert. Note that rebases rewrite history, so you should avoid rebasing
294+
published branches unless you're sure you're comfortable with that. See the
295+
NOTES section in linkgit:git-rebase[1] for more details.
296+
244297
Hooks
245298
-----
246299

@@ -310,6 +363,39 @@ information about how to configure files as text or binary.
310363
You can also control this behavior with the `core.whitespace` setting if you
311364
don't wish to remove the carriage returns from your line endings.
312365

366+
[[always-modified-files-case]]
367+
Why do I have a file that's always modified?::
368+
Internally, Git always stores file names as sequences of bytes and doesn't
369+
perform any encoding or case folding. However, Windows and macOS by default
370+
both perform case folding on file names. As a result, it's possible to end up
371+
with multiple files or directories whose names differ only in case. Git can
372+
handle this just fine, but the file system can store only one of these files,
373+
so when Git reads the other file to see its contents, it looks modified.
374+
+
375+
It's best to remove one of the files such that you only have one file. You can
376+
do this with commands like the following (assuming two files `AFile.txt` and
377+
`afile.txt`) on an otherwise clean working tree:
378+
+
379+
----
380+
$ git rm --cached AFile.txt
381+
$ git commit -m 'Remove files conflicting in case'
382+
$ git checkout .
383+
----
384+
+
385+
This avoids touching the disk, but removes the additional file. Your project
386+
may prefer to adopt a naming convention, such as all-lowercase names, to avoid
387+
this problem from occurring again; such a convention can be checked using a
388+
`pre-receive` hook or as part of a continuous integration (CI) system.
389+
+
390+
It is also possible for perpetually modified files to occur on any platform if a
391+
smudge or clean filter is in use on your system but a file was previously
392+
committed without running the smudge or clean filter. To fix this, run the
393+
following on an otherwise clean working tree:
394+
+
395+
----
396+
$ git add --renormalize .
397+
----
398+
313399
[[recommended-storage-settings]]
314400
What's the recommended way to store files in Git?::
315401
While Git can store and handle any file of any type, there are some

0 commit comments

Comments
 (0)