{"thread":{"id":"54234","subject":"[PATCH 0/3] FAQ entries for merges and modified files","startedAt":"2020-09-12T20:51:46Z","lastAt":"2020-09-20T23:23:36Z","messageCount":13,"participants":["brian m. carlson","Junio C Hamano","Martin Ågren"],"isPatch":true,"patchVersion":1,"patchTotal":3},"messages":[{"id":"405479","messageId":"20200912204824.2824106-1-sandals@crustytoothpaste.net","threadId":"54234","inReplyTo":null,"subject":"[PATCH 0/3] FAQ entries for merges and modified files","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2020-09-12T20:48:21Z","receivedAt":"2020-09-12T20:51:46Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"This series introduces a few new FAQ entries on various topics.\n\nThe first describes why squash merging doesn't work for long-running\nbranches.  This is confusing for a lot of folks, including some pretty\nadvanced developers, so it seems worth documenting.\n\nThe second explains why reverts are not applied on merge if the change\nhas been cherry-picked to both sides.  We have documentation on this\nalready in git-merge(1), but here we also advise using a rebase instead.\nI still see folks confused by this, so hopefully making it a little more\nvisible (with a little more explanation) will be helpful.\n\nThe third departs from the topic of merges to discuss modified files.  I\nfrequently see folks with perpetually modified files for one of two\nreasons: case-sensitivity problems and problems where someone failed to\nrun the smudge or clean filter.  In fact, we saw one of those problems\nrecently on the list.  The FAQ entry explains how to handle both\nsituations and provides suggestions to prevent the former from happening\nagain.\n\nI've answered all of these questions recently (some multiple times), so\nI figured I'd document this so that folks can hopefully discover more of\nthis themselves and solve their problems more quickly.\n\nbrian m. carlson (3):\n  docs: explain why squash merges are broken with long-running branches\n  docs: explain why reverts are not always applied on merge\n  docs: explain how to deal with files that are always modified\n\n Documentation/gitfaq.txt | 85 ++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 85 insertions(+)\n\n"},{"id":"405480","messageId":"20200912204824.2824106-4-sandals@crustytoothpaste.net","threadId":"54234","inReplyTo":"20200912204824.2824106-1-sandals@crustytoothpaste.net","subject":"[PATCH 3/3] docs: explain how to deal with files that are always modified","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2020-09-12T20:48:24Z","receivedAt":"2020-09-12T20:51:49Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"Users frequently have problems where two files differ only in case,\ncausing one of those files to show up consistently as being modified.\nLet's add a FAQ entry that explains how to deal with that.\n\nIn addition, let's explain another common case where files are\nconsistently modified, which is when files using a smudge or clean\nfilter have not been run through that filter.  Explain the way to fix\nthis as well.\n\nSigned-off-by: brian m. carlson <sandals@crustytoothpaste.net>\n---\n Documentation/gitfaq.txt | 33 +++++++++++++++++++++++++++++++++\n 1 file changed, 33 insertions(+)\n\ndiff --git a/Documentation/gitfaq.txt b/Documentation/gitfaq.txt\nindex 154f0cce54..494ec5dce5 100644\n--- a/Documentation/gitfaq.txt\n+++ b/Documentation/gitfaq.txt\n@@ -362,6 +362,39 @@ information about how to configure files as text or binary.\n You can also control this behavior with the `core.whitespace` setting if you\n don't wish to remove the carriage returns from your line endings.\n \n+[[always-modified-files-case]]\n+Why do I have a file that's always modified?::\n+\tInternally, Git always stores file names as sequences of bytes and doesn't\n+\tperform any encoding or case folding.  However, Windows and macOS by default\n+\tboth perform case folding on file names.  As a result, it's possible to end up\n+\twith multiple files or directories that differ in case.  Git can handle this\n+\tjust fine, but the file system can store only one of these files, so when Git\n+\treads the other file to see its contents, it looks modified.\n++\n+It's best to remove one of the files such that you only have one file.  You can\n+do this with commands like the following (assuming two files `AFile.txt` and\n+`afile.txt`) on an otherwise clean working tree:\n++\n+----\n+$ git rm --cached AFile.txt\n+$ git commit -m 'Remove files conflicting in case'\n+$ git checkout .\n+----\n++\n+This avoids touching the disk, but removes the additional file.  Your project\n+may prefer to adopt a naming convention, such as all-lowercase names, to avoid\n+this problem from occurring again; such a convention can be checked using a\n+`pre-receive` hook or as part of a continuous integration (CI) system.\n++\n+It is also possible for perpetually modified files to occur on any platform if a\n+smudge or clean filter is in use on your system but a file was previously\n+committed without running the smudge or clean filter.  To fix this, run the\n+following on an otherwise clean working tree:\n++\n+----\n+$ git add --renormalize .\n+----\n+\n [[recommended-storage-settings]]\n What's the recommended way to store files in Git?::\n \tWhile Git can store and handle any file of any type, there are some\n"},{"id":"405481","messageId":"20200912204824.2824106-3-sandals@crustytoothpaste.net","threadId":"54234","inReplyTo":"20200912204824.2824106-1-sandals@crustytoothpaste.net","subject":"[PATCH 2/3] docs: explain why reverts are not always applied on merge","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2020-09-12T20:48:23Z","receivedAt":"2020-09-12T20:52:16Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"A common scenario is for a user to apply a change to one branch and\ncherry-pick it into another, then later revert it in the first branch.\nThis results in the change being present when the two branches are\nmerge, which is confusing to many users.\n\nWe already have documentation for how this works in `git merge`, but it\nis clear from the frequency with which this is asked that it's hard to\ngrasp.  We also don't explain to users that they are better off doing a\nrebase in this case, which will do what they intended.  Let's add an\nentry to the FAQ telling users what's happening and advising them to use\nrebase here.\n\nSigned-off-by: brian m. carlson <sandals@crustytoothpaste.net>\n---\n Documentation/gitfaq.txt | 19 +++++++++++++++++++\n 1 file changed, 19 insertions(+)\n\ndiff --git a/Documentation/gitfaq.txt b/Documentation/gitfaq.txt\nindex 550f4e30d6..154f0cce54 100644\n--- a/Documentation/gitfaq.txt\n+++ b/Documentation/gitfaq.txt\n@@ -274,6 +274,25 @@ original merge base.\n As a consequence, if you want to merge two long-running branches, it's best to\n always use a regular merge commit.\n \n+[[merge-two-revert-one]]\n+If I make a change on two branches but revert it on one, why does the merge of those branches include the change?::\n+\tBy default, when Git does a merge, it uses a strategy called the recursive\n+\tstrategy, which does a fancy three-way merge.  In such a case, when Git\n+\tperforms the merge, it considers exactly three points: the two heads and a\n+\tthird point, called the _merge base_, which is usually the common ancestor of\n+\tthose commits.  Git does not consider the history or the individual commits\n+\tthat have happened on those branches at all.\n++\n+As a result, if both sides have a change and one side has reverted that change,\n+the result is to include the change.  This is because the code has changed on\n+one side and there is no net change on the other, and in this scenario, Git\n+adopts the change.\n++\n+If this is a problem for you, you can do a rebase instead, rebasing the branch\n+with the revert onto the other branch.  A rebase in this scenario will revert\n+the change, because a rebase applies each individual commit, including the\n+revert.\n+\n Hooks\n -----\n \n"},{"id":"405482","messageId":"20200912204824.2824106-2-sandals@crustytoothpaste.net","threadId":"54234","inReplyTo":"20200912204824.2824106-1-sandals@crustytoothpaste.net","subject":"[PATCH 1/3] docs: explain why squash merges are broken with long-running branches","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2020-09-12T20:48:22Z","receivedAt":"2020-09-12T20:52:17Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"In many projects, squash merges are commonly used, primarily to keep a\ntidy history in the face of developers who do not use logically\nindependent, bisectable commits.  As common as this is, this tends to\ncause significant problems when squash merges are used to merge\nlong-running branches due to the lack of any new merge bases.  Even very\nexperienced developers may make this mistakes, so let's add a FAQ entry\nexplaining why this is problematic and explaining that regular merge\ncommits should be used to merge two long-running branches.\n\nSigned-off-by: brian m. carlson <sandals@crustytoothpaste.net>\n---\n Documentation/gitfaq.txt | 33 +++++++++++++++++++++++++++++++++\n 1 file changed, 33 insertions(+)\n\ndiff --git a/Documentation/gitfaq.txt b/Documentation/gitfaq.txt\nindex 9cd7a592ac..550f4e30d6 100644\n--- a/Documentation/gitfaq.txt\n+++ b/Documentation/gitfaq.txt\n@@ -241,6 +241,39 @@ How do I know if I want to do a fetch or a pull?::\n \tignore the upstream changes.  A pull consists of a fetch followed\n \timmediately by either a merge or rebase.  See linkgit:git-pull[1].\n \n+Merging and Rebasing\n+--------------------\n+\n+[[long-running-squash-merge]]\n+What kinds of problems can occur when merging long-running branches with squash merges?::\n+\tIn general, there are a variety of problems that can occur when using squash\n+\tmerges with long-running branches.  These can include seeing extra commits in\n+\t`git log` output, with a GUI, or when using the `...` notation to express a\n+\trange, as well as the possibility of needing to re-resolve conflicts again and\n+\tagain.\n++\n+When Git does a normal merge between two branches, it considers exactly three\n+points: the two branches and a third commit, called the _merge base_, which is\n+usually the common ancestor of the commits.  The result of the merge is the sum\n+of the changes between the merge base and each head.  When you merge two\n+long-running branches with a regular merge commit, this results in a new commit\n+which will end up as a merge base when they're merged again, because there is\n+now a new common ancestor.  Git doesn't have to consider changes that occurred\n+before the merge base, so you don't have to re-resolve any conflicts you\n+resolved before.\n++\n+When you perform a squash merge, a merge commit isn't created; instead, the\n+changes from one side are applied as a regular commit to the other side.  This\n+means that the merge base for these branches won't have changed, and so when Git\n+goes to perform its next merge, it considers all of the changes that it\n+considered the last time plus the new changes.  That means any conflicts may\n+need to be re-resolved.  Similarly, anything using the `...` notation in `git\n+diff`, `git log`, or a GUI will result in showing all of the changes since the\n+original merge base.\n++\n+As a consequence, if you want to merge two long-running branches, it's best to\n+always use a regular merge commit.\n+\n Hooks\n -----\n \n"},{"id":"405485","messageId":"xmqqwo0ymzu2.fsf@gitster.c.googlers.com","threadId":"54234","inReplyTo":"20200912204824.2824106-1-sandals@crustytoothpaste.net","subject":"Re: [PATCH 0/3] FAQ entries for merges and modified files","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-09-12T21:48:05Z","receivedAt":"2020-09-12T21:48:17Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"brian m. carlson\" <sandals@crustytoothpaste.net> writes:\n\n> This series introduces a few new FAQ entries on various topics.\n\nAll look like topics worth covering.\n\nThanks.\n"},{"id":"405499","messageId":"CAN0heSo8XsToRm1st4PqPp8PNwc98Csx-+o78J-mh3bbYoneWQ@mail.gmail.com","threadId":"54234","inReplyTo":"20200912204824.2824106-2-sandals@crustytoothpaste.net","subject":"Re: [PATCH 1/3] docs: explain why squash merges are broken with long-running branches","fromName":"Martin Ågren","fromEmail":"martin.agren@gmail.com","sentAt":"2020-09-13T15:05:31Z","receivedAt":"2020-09-13T15:05:47Z","isPatch":true,"sender":{"key":"martin.agren@gmail.com","avatar":null},"body":"On Sat, 12 Sep 2020 at 22:52, brian m. carlson\n<sandals@crustytoothpaste.net> wrote:\n>\n> In many projects, squash merges are commonly used, primarily to keep a\n> tidy history in the face of developers who do not use logically\n> independent, bisectable commits.  As common as this is, this tends to\n> cause significant problems when squash merges are used to merge\n> long-running branches due to the lack of any new merge bases.  Even very\n> experienced developers may make this mistakes, so let's add a FAQ entry\n\ns/mistakes/mistake/\n\n> explaining why this is problematic and explaining that regular merge\n> commits should be used to merge two long-running branches.\n\n> +What kinds of problems can occur when merging long-running branches with squash merges?::\n> +       In general, there are a variety of problems that can occur when using squash\n> +       merges with long-running branches.  These can include seeing extra commits in\n> +       `git log` output, with a GUI, or when using the `...` notation to express a\n> +       range, as well as the possibility of needing to re-resolve conflicts again and\n> +       again.\n\nVery well-written, as always.\n\nI grepped around a little and couldn't find that we're using this \"long-\nrunning branch\" notion anywhere. I think it might make sense to\ndefine/explain that somewhere early, e.g., with something like \"...\nmerged repeatedly ... more development...\".\n\nSo in particular, a \"long-running\" branch is not something like\n\n  I branched off a long time ago, I've been hacking on this feature for\n  a long time and the branch has run quite long with lots of commits.\n  Now it's time to merge it and be done with it!\n\nOnce that piece of background is in place, what you have here reads very\nwell to me. It was only somewhere halfway through the second paragraph\nthat I got what you meant by \"long-running branch\".\n\n\nMartin\n"},{"id":"405500","messageId":"CAN0heSrQR+6SsPHFtqcjYeFe1ce5USTxkxLXZ4g2MCqbV20K6g@mail.gmail.com","threadId":"54234","inReplyTo":"20200912204824.2824106-3-sandals@crustytoothpaste.net","subject":"Re: [PATCH 2/3] docs: explain why reverts are not always applied on merge","fromName":"Martin Ågren","fromEmail":"martin.agren@gmail.com","sentAt":"2020-09-13T15:12:00Z","receivedAt":"2020-09-13T15:12:17Z","isPatch":true,"sender":{"key":"martin.agren@gmail.com","avatar":null},"body":"On Sat, 12 Sep 2020 at 22:51, brian m. carlson\n<sandals@crustytoothpaste.net> wrote:\n>\n> A common scenario is for a user to apply a change to one branch and\n> cherry-pick it into another, then later revert it in the first branch.\n> This results in the change being present when the two branches are\n> merge, which is confusing to many users.\n\ns/merge/&d/\n\n> +If this is a problem for you, you can do a rebase instead, rebasing the branch\n> +with the revert onto the other branch.  A rebase in this scenario will revert\n> +the change, because a rebase applies each individual commit, including the\n> +revert.\n\nShould this include the usual disclaimer about only rebasing a branch if\nit hasn't been published or if you (and your team) is willing and able\nto handle the fallout? I dunno. This piece of text is vague enough that\nthe reader will have to pick up the \"rebase ... onto\" keywords and\nfigure out the details some other way (and to be clear: I think that's a\ngood thing). I think that should be sufficient and they'll find the\ndisclaimer when they look up \"rebase\", if they don't already know it.\n\n\nMartin\n"},{"id":"405501","messageId":"CAN0heSp-Uhp9QZdjV3GeUkhMn513-GADJg1D9UXsrB7ok8J_gw@mail.gmail.com","threadId":"54234","inReplyTo":"20200912204824.2824106-4-sandals@crustytoothpaste.net","subject":"Re: [PATCH 3/3] docs: explain how to deal with files that are always modified","fromName":"Martin Ågren","fromEmail":"martin.agren@gmail.com","sentAt":"2020-09-13T15:13:10Z","receivedAt":"2020-09-13T15:13:33Z","isPatch":true,"sender":{"key":"martin.agren@gmail.com","avatar":null},"body":"On Sat, 12 Sep 2020 at 22:52, brian m. carlson\n<sandals@crustytoothpaste.net> wrote:\n>\n> Users frequently have problems where two files differ only in case,\n\ns/files/filenames/ ? Anyway, clear enough here, but let's keep it in\nmind when reading the proposed FAQ entry..\n\n> causing one of those files to show up consistently as being modified.\n> Let's add a FAQ entry that explains how to deal with that.\n>\n> In addition, let's explain another common case where files are\n> consistently modified, which is when files using a smudge or clean\n> filter have not been run through that filter.  Explain the way to fix\n> this as well.\n\n> +Why do I have a file that's always modified?::\n> +       Internally, Git always stores file names as sequences of bytes and doesn't\n> +       perform any encoding or case folding.  However, Windows and macOS by default\n> +       both perform case folding on file names.  As a result, it's possible to end up\n> +       with multiple files or directories that differ in case.  Git can handle this\n\nI think this could be clearer with something like s/that differ in case/where\ntheir names only differ in case/, i.e., explicitly talking about the names\nof the files and also sticking an \"only\" in there.\n\n> +       just fine, but the file system can store only one of these files, so when Git\n> +       reads the other file to see its contents, it looks modified.\n\nThat concludes my reading of these patches. I only had some minor\ncomments. I think these are good entries to add to the FAQ.\n\n\nMartin\n"},{"id":"405503","messageId":"20200913171206.GO241078@camp.crustytoothpaste.net","threadId":"54234","inReplyTo":"CAN0heSo8XsToRm1st4PqPp8PNwc98Csx-+o78J-mh3bbYoneWQ@mail.gmail.com","subject":"Re: [PATCH 1/3] docs: explain why squash merges are broken with long-running branches","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2020-09-13T17:12:06Z","receivedAt":"2020-09-13T17:12:47Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On 2020-09-13 at 15:05:31, Martin Ågren wrote:\n> On Sat, 12 Sep 2020 at 22:52, brian m. carlson\n> <sandals@crustytoothpaste.net> wrote:\n> >\n> > In many projects, squash merges are commonly used, primarily to keep a\n> > tidy history in the face of developers who do not use logically\n> > independent, bisectable commits.  As common as this is, this tends to\n> > cause significant problems when squash merges are used to merge\n> > long-running branches due to the lack of any new merge bases.  Even very\n> > experienced developers may make this mistakes, so let's add a FAQ entry\n> \n> s/mistakes/mistake/\n\nWill fix.\n\n> Very well-written, as always.\n> \n> I grepped around a little and couldn't find that we're using this \"long-\n> running branch\" notion anywhere. I think it might make sense to\n> define/explain that somewhere early, e.g., with something like \"...\n> merged repeatedly ... more development...\".\n> \n> So in particular, a \"long-running\" branch is not something like\n> \n>   I branched off a long time ago, I've been hacking on this feature for\n>   a long time and the branch has run quite long with lots of commits.\n>   Now it's time to merge it and be done with it!\n\nCorrect.  By \"long-running branch\", I mean a branch into which code\nroutinely gets integrated from feature branches.  For example, the\nbranches master and develop in a Git Flow workflow, or per-version\nrelease branches if you use that workflow.  I didn't mean an otherwise\ndivergent branch which has persisted for a long time.\n\nThe problem happens, essentially, if you have two branches and you merge\none of them into another repeatedly with squash merges, so I'll be sure\nto make that clear.  That will probably help with intelligibility for\nnon-native speakers as well.\n\n> Once that piece of background is in place, what you have here reads very\n> well to me. It was only somewhere halfway through the second paragraph\n> that I got what you meant by \"long-running branch\".\n\nThanks, this is helpful feedback.\n-- \nbrian m. carlson: Houston, Texas, US\n"},{"id":"406006","messageId":"20200920232231.1300394-3-sandals@crustytoothpaste.net","threadId":"54234","inReplyTo":"20200920232231.1300394-1-sandals@crustytoothpaste.net","subject":"[PATCH v2 2/3] docs: explain why reverts are not always applied on merge","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2020-09-20T23:22:30Z","receivedAt":"2020-09-20T23:23:14Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"A common scenario is for a user to apply a change to one branch and\ncherry-pick it into another, then later revert it in the first branch.\nThis results in the change being present when the two branches are\nmerged, which is confusing to many users.\n\nWe already have documentation for how this works in `git merge`, but it\nis clear from the frequency with which this is asked that it's hard to\ngrasp.  We also don't explain to users that they are better off doing a\nrebase in this case, which will do what they intended.  Let's add an\nentry to the FAQ telling users what's happening and advising them to use\nrebase here.\n\nSigned-off-by: brian m. carlson <sandals@crustytoothpaste.net>\n---\n Documentation/gitfaq.txt | 21 +++++++++++++++++++++\n 1 file changed, 21 insertions(+)\n\ndiff --git a/Documentation/gitfaq.txt b/Documentation/gitfaq.txt\nindex 51d305d58f..176b097cf7 100644\n--- a/Documentation/gitfaq.txt\n+++ b/Documentation/gitfaq.txt\n@@ -273,6 +273,27 @@ original merge base.\n As a consequence, if you want to merge two long-lived branches repeatedly, it's\n best to always use a regular merge commit.\n \n+[[merge-two-revert-one]]\n+If I make a change on two branches but revert it on one, why does the merge of those branches include the change?::\n+\tBy default, when Git does a merge, it uses a strategy called the recursive\n+\tstrategy, which does a fancy three-way merge.  In such a case, when Git\n+\tperforms the merge, it considers exactly three points: the two heads and a\n+\tthird point, called the _merge base_, which is usually the common ancestor of\n+\tthose commits.  Git does not consider the history or the individual commits\n+\tthat have happened on those branches at all.\n++\n+As a result, if both sides have a change and one side has reverted that change,\n+the result is to include the change.  This is because the code has changed on\n+one side and there is no net change on the other, and in this scenario, Git\n+adopts the change.\n++\n+If this is a problem for you, you can do a rebase instead, rebasing the branch\n+with the revert onto the other branch.  A rebase in this scenario will revert\n+the change, because a rebase applies each individual commit, including the\n+revert.  Note that rebases rewrite history, so you should avoid rebasing\n+published branches unless you're sure you're comfortable with that.  See the\n+NOTES section in linkgit:git-rebase[1] for more details.\n+\n Hooks\n -----\n \n"},{"id":"406007","messageId":"20200920232231.1300394-2-sandals@crustytoothpaste.net","threadId":"54234","inReplyTo":"20200920232231.1300394-1-sandals@crustytoothpaste.net","subject":"[PATCH v2 1/3] docs: explain why squash merges are broken with long-running branches","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2020-09-20T23:22:29Z","receivedAt":"2020-09-20T23:23:14Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"In many projects, squash merges are commonly used, primarily to keep a\ntidy history in the face of developers who do not use logically\nindependent, bisectable commits.  As common as this is, this tends to\ncause significant problems when squash merges are used to merge\nlong-running branches due to the lack of any new merge bases.  Even very\nexperienced developers may make this mistake, so let's add a FAQ entry\nexplaining why this is problematic and explaining that regular merge\ncommits should be used to merge two long-running branches.\n\nSigned-off-by: brian m. carlson <sandals@crustytoothpaste.net>\n---\n Documentation/gitfaq.txt | 32 ++++++++++++++++++++++++++++++++\n 1 file changed, 32 insertions(+)\n\ndiff --git a/Documentation/gitfaq.txt b/Documentation/gitfaq.txt\nindex 9cd7a592ac..51d305d58f 100644\n--- a/Documentation/gitfaq.txt\n+++ b/Documentation/gitfaq.txt\n@@ -241,6 +241,38 @@ How do I know if I want to do a fetch or a pull?::\n \tignore the upstream changes.  A pull consists of a fetch followed\n \timmediately by either a merge or rebase.  See linkgit:git-pull[1].\n \n+Merging and Rebasing\n+--------------------\n+\n+[[long-running-squash-merge]]\n+What kinds of problems can occur when merging long-lived branches with squash merges?::\n+\tIn general, there are a variety of problems that can occur when using squash\n+\tmerges to merge two branches multiple times.  These can include seeing extra\n+\tcommits in `git log` output, with a GUI, or when using the `...` notation to\n+\texpress a range, as well as the possibility of needing to re-resolve conflicts\n+\tagain and again.\n++\n+When Git does a normal merge between two branches, it considers exactly three\n+points: the two branches and a third commit, called the _merge base_, which is\n+usually the common ancestor of the commits.  The result of the merge is the sum\n+of the changes between the merge base and each head.  When you merge two\n+branches with a regular merge commit, this results in a new commit which will\n+end up as a merge base when they're merged again, because there is now a new\n+common ancestor.  Git doesn't have to consider changes that occurred before the\n+merge base, so you don't have to re-resolve any conflicts you resolved before.\n++\n+When you perform a squash merge, a merge commit isn't created; instead, the\n+changes from one side are applied as a regular commit to the other side.  This\n+means that the merge base for these branches won't have changed, and so when Git\n+goes to perform its next merge, it considers all of the changes that it\n+considered the last time plus the new changes.  That means any conflicts may\n+need to be re-resolved.  Similarly, anything using the `...` notation in `git\n+diff`, `git log`, or a GUI will result in showing all of the changes since the\n+original merge base.\n++\n+As a consequence, if you want to merge two long-lived branches repeatedly, it's\n+best to always use a regular merge commit.\n+\n Hooks\n -----\n \n"},{"id":"406008","messageId":"20200920232231.1300394-1-sandals@crustytoothpaste.net","threadId":"54234","inReplyTo":"20200912204824.2824106-1-sandals@crustytoothpaste.net","subject":"[PATCH v2 0/3] FAQ entries for merges and modified files","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2020-09-20T23:22:28Z","receivedAt":"2020-09-20T23:23:14Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"This series introduces a few new FAQ entries on various topics.\n\nChanges from v1:\n* Fix typos in commit messages.\n* Talk about case-insensitive file names, not files, to avoid ambiguity.\n* Warn people about rebases.\n* Switch from \"long-running\" to \"long-lived\" and explain the situation\n  more clearly without relying on people understanding the meaning of\n  the adjective.\n\nbrian m. carlson (3):\n  docs: explain why squash merges are broken with long-running branches\n  docs: explain why reverts are not always applied on merge\n  docs: explain how to deal with files that are always modified\n\n Documentation/gitfaq.txt | 86 ++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 86 insertions(+)\n\nDiff-intervalle contre v1 :\n1:  c4f3e6e19c ! 1:  9f8f348fa8 docs: explain why squash merges are broken with long-running branches\n    @@ Commit message\n         independent, bisectable commits.  As common as this is, this tends to\n         cause significant problems when squash merges are used to merge\n         long-running branches due to the lack of any new merge bases.  Even very\n    -    experienced developers may make this mistakes, so let's add a FAQ entry\n    +    experienced developers may make this mistake, so let's add a FAQ entry\n         explaining why this is problematic and explaining that regular merge\n         commits should be used to merge two long-running branches.\n     \n    @@ Documentation/gitfaq.txt: How do I know if I want to do a fetch or a pull?::\n     +--------------------\n     +\n     +[[long-running-squash-merge]]\n    -+What kinds of problems can occur when merging long-running branches with squash merges?::\n    ++What kinds of problems can occur when merging long-lived branches with squash merges?::\n     +\tIn general, there are a variety of problems that can occur when using squash\n    -+\tmerges with long-running branches.  These can include seeing extra commits in\n    -+\t`git log` output, with a GUI, or when using the `...` notation to express a\n    -+\trange, as well as the possibility of needing to re-resolve conflicts again and\n    -+\tagain.\n    ++\tmerges to merge two branches multiple times.  These can include seeing extra\n    ++\tcommits in `git log` output, with a GUI, or when using the `...` notation to\n    ++\texpress a range, as well as the possibility of needing to re-resolve conflicts\n    ++\tagain and again.\n     ++\n     +When Git does a normal merge between two branches, it considers exactly three\n     +points: the two branches and a third commit, called the _merge base_, which is\n     +usually the common ancestor of the commits.  The result of the merge is the sum\n     +of the changes between the merge base and each head.  When you merge two\n    -+long-running branches with a regular merge commit, this results in a new commit\n    -+which will end up as a merge base when they're merged again, because there is\n    -+now a new common ancestor.  Git doesn't have to consider changes that occurred\n    -+before the merge base, so you don't have to re-resolve any conflicts you\n    -+resolved before.\n    ++branches with a regular merge commit, this results in a new commit which will\n    ++end up as a merge base when they're merged again, because there is now a new\n    ++common ancestor.  Git doesn't have to consider changes that occurred before the\n    ++merge base, so you don't have to re-resolve any conflicts you resolved before.\n     ++\n     +When you perform a squash merge, a merge commit isn't created; instead, the\n     +changes from one side are applied as a regular commit to the other side.  This\n    @@ Documentation/gitfaq.txt: How do I know if I want to do a fetch or a pull?::\n     +diff`, `git log`, or a GUI will result in showing all of the changes since the\n     +original merge base.\n     ++\n    -+As a consequence, if you want to merge two long-running branches, it's best to\n    -+always use a regular merge commit.\n    ++As a consequence, if you want to merge two long-lived branches repeatedly, it's\n    ++best to always use a regular merge commit.\n     +\n      Hooks\n      -----\n2:  645798d18b ! 2:  248d7e7b4b docs: explain why reverts are not always applied on merge\n    @@ Commit message\n         A common scenario is for a user to apply a change to one branch and\n         cherry-pick it into another, then later revert it in the first branch.\n         This results in the change being present when the two branches are\n    -    merge, which is confusing to many users.\n    +    merged, which is confusing to many users.\n     \n         We already have documentation for how this works in `git merge`, but it\n         is clear from the frequency with which this is asked that it's hard to\n    @@ Commit message\n     \n      ## Documentation/gitfaq.txt ##\n     @@ Documentation/gitfaq.txt: original merge base.\n    - As a consequence, if you want to merge two long-running branches, it's best to\n    - always use a regular merge commit.\n    + As a consequence, if you want to merge two long-lived branches repeatedly, it's\n    + best to always use a regular merge commit.\n      \n     +[[merge-two-revert-one]]\n     +If I make a change on two branches but revert it on one, why does the merge of those branches include the change?::\n    @@ Documentation/gitfaq.txt: original merge base.\n     +If this is a problem for you, you can do a rebase instead, rebasing the branch\n     +with the revert onto the other branch.  A rebase in this scenario will revert\n     +the change, because a rebase applies each individual commit, including the\n    -+revert.\n    ++revert.  Note that rebases rewrite history, so you should avoid rebasing\n    ++published branches unless you're sure you're comfortable with that.  See the\n    ++NOTES section in linkgit:git-rebase[1] for more details.\n     +\n      Hooks\n      -----\n3:  10ad244b1e ! 3:  e2495d4358 docs: explain how to deal with files that are always modified\n    @@ Metadata\n      ## Commit message ##\n         docs: explain how to deal with files that are always modified\n     \n    -    Users frequently have problems where two files differ only in case,\n    +    Users frequently have problems where two filenames differ only in case,\n         causing one of those files to show up consistently as being modified.\n         Let's add a FAQ entry that explains how to deal with that.\n     \n    @@ Documentation/gitfaq.txt: information about how to configure files as text or bi\n     +\tInternally, Git always stores file names as sequences of bytes and doesn't\n     +\tperform any encoding or case folding.  However, Windows and macOS by default\n     +\tboth perform case folding on file names.  As a result, it's possible to end up\n    -+\twith multiple files or directories that differ in case.  Git can handle this\n    -+\tjust fine, but the file system can store only one of these files, so when Git\n    -+\treads the other file to see its contents, it looks modified.\n    ++\twith multiple files or directories whose names differ only in case.  Git can\n    ++\thandle this just fine, but the file system can store only one of these files,\n    ++\tso when Git reads the other file to see its contents, it looks modified.\n     ++\n     +It's best to remove one of the files such that you only have one file.  You can\n     +do this with commands like the following (assuming two files `AFile.txt` and\n"},{"id":"406009","messageId":"20200920232231.1300394-4-sandals@crustytoothpaste.net","threadId":"54234","inReplyTo":"20200920232231.1300394-1-sandals@crustytoothpaste.net","subject":"[PATCH v2 3/3] docs: explain how to deal with files that are always modified","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2020-09-20T23:22:31Z","receivedAt":"2020-09-20T23:23:36Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"Users frequently have problems where two filenames differ only in case,\ncausing one of those files to show up consistently as being modified.\nLet's add a FAQ entry that explains how to deal with that.\n\nIn addition, let's explain another common case where files are\nconsistently modified, which is when files using a smudge or clean\nfilter have not been run through that filter.  Explain the way to fix\nthis as well.\n\nSigned-off-by: brian m. carlson <sandals@crustytoothpaste.net>\n---\n Documentation/gitfaq.txt | 33 +++++++++++++++++++++++++++++++++\n 1 file changed, 33 insertions(+)\n\ndiff --git a/Documentation/gitfaq.txt b/Documentation/gitfaq.txt\nindex 176b097cf7..afdaeab850 100644\n--- a/Documentation/gitfaq.txt\n+++ b/Documentation/gitfaq.txt\n@@ -363,6 +363,39 @@ information about how to configure files as text or binary.\n You can also control this behavior with the `core.whitespace` setting if you\n don't wish to remove the carriage returns from your line endings.\n \n+[[always-modified-files-case]]\n+Why do I have a file that's always modified?::\n+\tInternally, Git always stores file names as sequences of bytes and doesn't\n+\tperform any encoding or case folding.  However, Windows and macOS by default\n+\tboth perform case folding on file names.  As a result, it's possible to end up\n+\twith multiple files or directories whose names differ only in case.  Git can\n+\thandle this just fine, but the file system can store only one of these files,\n+\tso when Git reads the other file to see its contents, it looks modified.\n++\n+It's best to remove one of the files such that you only have one file.  You can\n+do this with commands like the following (assuming two files `AFile.txt` and\n+`afile.txt`) on an otherwise clean working tree:\n++\n+----\n+$ git rm --cached AFile.txt\n+$ git commit -m 'Remove files conflicting in case'\n+$ git checkout .\n+----\n++\n+This avoids touching the disk, but removes the additional file.  Your project\n+may prefer to adopt a naming convention, such as all-lowercase names, to avoid\n+this problem from occurring again; such a convention can be checked using a\n+`pre-receive` hook or as part of a continuous integration (CI) system.\n++\n+It is also possible for perpetually modified files to occur on any platform if a\n+smudge or clean filter is in use on your system but a file was previously\n+committed without running the smudge or clean filter.  To fix this, run the\n+following on an otherwise clean working tree:\n++\n+----\n+$ git add --renormalize .\n+----\n+\n [[recommended-storage-settings]]\n What's the recommended way to store files in Git?::\n \tWhile Git can store and handle any file of any type, there are some\n"}]}