uses a strategy called the `ort`
strategy, which does a fancy three-way merge. In such a case, when Git
performs the merge, it considers exactly three points: the two heads and a
third point, called the _merge base_, which is usually the common ancestor of
those commits. Git does not consider the history or the individual commits
that have happened on those branches at all.
+
As a result, if both sides have a change and one side has reverted that change,
the result is to include the change. This is because the code has changed on
one side and there is no net change on the other, and in this scenario, Git
adopts the change.
+
If this is a problem for you, you can do a rebase instead, rebasing the branch
with the revert onto the other branch. A rebase in this scenario will revert
the change, because a rebase applies each individual commit, including the
revert. Note that rebases rewrite history, so you should avoid rebasing
published branches unless you're sure you're comfortable with that. See the
NOTES section in linkgit:git-rebase[1] for more details.
Hooks
-----
[[restrict-with-hooks]]
How do I use hooks to prevent users from making certain changes?::
The only safe place to make these changes is on the remote repository
(i.e., the Git server), usually in the `pre-receive` hook or in a
continuous integration (CI) system. These are the locations in which
policy can be enforced effectively.
+
It's common to try to use `pre-commit` hooks (or, for commit messages,
`commit-msg` hooks) to check these things, which is great if you're working as a
solo developer and want the tooling to help you. However, using hooks on a
developer machine is not effective as a policy control because a user can bypass
these hooks with `--no-verify` without being noticed (among various other ways).
Git assumes that the user is in control of their local repositories and doesn't
try to prevent this or tattle on the user.
+
In addition, some advanced users find `pre-commit` hooks to be an impediment to
workflows that use temporary commits to stage work in progress or that create
fixup commits, so it's better to push these kinds of checks to the server
anyway.
Cross-Platform Issues
---------------------
[[windows-text-binary]]
I'm on Windows and my text files are detected as binary.::
Git works best when you store text files as UTF-8. Many programs on
Windows support UTF-8, but some do not and only use the little-endian
UTF-16 format, which Git detects as binary. If you can't use UTF-8 with
your programs, you can specify a working tree encoding that indicates
which encoding your files should be checked out with, while still
storing these files as UTF-8 in the repository. This allows tools like
linkgit:git-diff[1] to work as expected, while still allowing your tools
to work.
+
To do so, you can specify a linkgit:gitattributes[5] pattern with the
`working-tree-encoding` attribute. For example, the following pattern sets all
C files to use UTF-16LE-BOM, which is a common encoding on Windows:
+
----
*.c working-tree-encoding=UTF-16LE-BOM
----
+
You will need to run `git add --renormalize` to have this take effect. Note
that if you are making these changes on a project that is used across platforms,
you'll probably want to make it in a per-user configuration file or in the one
in `$GIT_DIR/info/attributes`, since making it in a `.gitattributes` file in the
repository will apply to all users of the repository.
+
See the following entry for information about normalizing line endings as well,
and see linkgit:gitattributes[5] for more information about attribute files.
[[windows-diff-control-m]]
I'm on Windows and git diff shows my files as having a `^M` at the end.::
By default, Git expects files to be stored with Unix line endings. As such,
the carriage return (`^M`) that is part of a Windows line ending is shown
because it is considered to be trailing whitespace. Git defaults to showing
trailing whitespace only on new lines,