[RFR] gitattributes(5) documentation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Here is my current draft.  I have build-infrastructure updates
to deal with a new manual section "man5/" (file formats) already
but that is boring stuff, so I am sending out only the new file
to be added for review.

We probably would want to have gitconfig(5) to describe its file
format, and include::config.txt[] in there as well.

Although I do not think it is particularly necessary, we _might_
want to also have gitdata(5) that describes the file format of
$GIT_DIR/index, loose objects, .pack, .idx, packed-refs.

-- >8 -- Documentation/gitattributes.txt -- >8 --

gitattributes(5)
================

NAME
----
gitattributes - defining attributes per path

SYNOPSIS
--------
.gitattributes


DESCRIPTION
-----------

A `gitattributes` file is a simple text file that gives
`attributes` to pathnames.

Each line in `gitattributes` file is of form:

	glob	attr1 attr2 ...

That is, a glob pattern followed by an attributes list,
separated by whitespaces.  When the glob pattern matches the
path in question, the list of attributes are given to the path.

Each attribute can be in one of these states for a given path:

Set::

	The path has the attribute with special value "true";
	this is specified by listing only the name of the
	attribute in the attribute list.

Unset::

	The path has the attribute with special value "false";
	this is specified by listing the name of the attribute
	prefixed with a dash `-` in the attribute list.

Set to a value::

	The path has the attribute with specified string value;
	this is specified by listing the name of the attribute
	followed by an equal sign `=` and its value in the
	attribute list.

Unspecified::

	No glob pattern matches the path, and nothing says if
	the path has or does not have the attribute.

When more than one glob pattern matches the path, a later line
that matches overrides an earlier line.

When deciding what attributes are assigned to a path, git
consults `.gitattributes` file in the same directory as the path
in question, and its parent directories, and then finally
`$GIT_DIR/info/attributes` file, in this order.

Sometimes you would need to override an setting of an attribute
for a path to `unspecified` state.  This can be done by listing
the name of the attribute prefixed with an exclamation point `!`.


EFFECTS
-------

Certain operations by git can be influenced by assigning
particular attributes to a path.  Currently, three operations
are attributes-aware.

Checking-out and checking-in
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The attribute `crlf` affects how the contents stored in the
repository are copied to the working tree files when commands
such as `git checkout` and `git merge` is run.  It also affects
how the contents you prepare in the working tree is stored back
in the repository when you do `git add` and `git commit`.

Set::
	A path to which the `crlf` attribute is set is converted
	to have CRLF line endings in the working tree upon
	checkout, and converted back to strip CRLF line endings
	to LF line endings upon checkin.

Unset::
	A path to which the `crlf` attribute is unset (do not
	confuse this with 'unspecified') does not go through
	line endings conversion upon checkin/checkout.

Unspecified::
	If the configuration variable `core.autocrlf` is false, no
	conversion is done for paths with `crlf` attribute
	unspecified.
+
Othewise, the contents of the path is inspected, and if it does
not look like a text file, no conversion is done.
+
If `core.autocrlf` is true, and the contents of the path does
look like a text file, line endings are converted to CRLF upon
checkout and LF upon checkin.
+
If `core.autocrlf` is set to "input", and the contents of the
path does look like a text file, line endings are converted to
LF upon checkin, but there is no conversion done upon checkout.

Any other value set to `crlf` attribute is ignored and git acts
as if the attribute is left unspecified.


Generating diff text
~~~~~~~~~~~~~~~~~~~~

The attribute `diff` affects if `git diff` generates textual
patch for the path or just says `Binary files differ`.

Set::
	A path to which the `crlf` attribute is set is treated
	as text, even when they contain funny bytes such as NUL.

Unset::
	A path to which the `crlf` attribute is unset will
	generate `Binary files differ`.

Unspecified::
	A path to which the `crlf` attribute is unspecified
	first gets its contents inspected, and if it looks like
	text, it is treated as text.  Otherwise it would
	generate `Binary files differ`.

Any other value set to `diff` attribute is ignored and git acts
as if the attribute is left unspecified.


Performing a three-way merge
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The attribute `merge` affects how three versions of a file is
merged when a file-level merge is necessary during `git merge`,
and other programs such as `git revert` and `git cherry-pick`.

Set::
	Built-in 3-way merge driver is used to merge the
	contents in a way similar to `merge` command of `RCS`
	suite.  This is suitable for ordinary text files.

Unset::
	Take the version from the current branch as the
	tentative merge result, and declare that the merge has
	conflicts.  This is suitable for binary files that does
	not have a well-defined merge semantics.

Unspecified::
	By default, this uses the same built-in 3-way merge
	driver as is the case the `merge` attribute is set.
	However, `merge.default` configuration variable can name
	different merge driver to be used for paths to which the
	`merge` attribute is unspecified.

Other string value::
	3-way merge is performed using the specified custom
	merge driver.  The built-in 3-way merge driver can be
	explicitly specified by asking for "text" driver; the
	built-in "take the current branch" driver can be
	requested by "binary".

Defining a custom merge driver
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The definition of a merge driver is done in `gitconfig` not
`gitattributes` file, so strictly speaking this manual page is a
wrong place to talk about it.  However...

To define a custom merge driver `filfre`, add a section to your
`$GIT_DIR/config` file (or `$HOME/.gitconfig` file) like this:

----------------------------------------------------------------
[merge "filfre"]
	name = feel-free merge driver
	driver = filfre %O %A %B
	recursive = binary
----------------------------------------------------------------

The `merge.*.name` variable gives the driver a human-readable
name.

The `merge.*.driver` variable's value is used to construct a
command to run to merge ancestor's version (`%O`), current
version (`%A`) and the other branches' version (`%B`).  These
three tokens are replaced with the names of temporary files that
hold the contents of these versions when the command line is
built.

The merge driver is expected to leave the result of the merge in
the file named with `%A` by overwriting it, and exit with zero
status if it managed to merge them cleanly, or non-zero if there
were conflicts.

The `merge.*.recursive` variable specifies what other merge
driver to use when the merge driver is called for an internal
merge between common ancestors, when there are more than one.
When left unspecified, the driver itself is used for both
internal merge and the final merge.


EXAMPLE
-------

If you have these three `gitattributes` file:

----------------------------------------------------------------
(in $GIT_DIR/info/attributes)

a*	foo !bar -baz

(in .gitattributes)
abc	foo bar baz

(in t/.gitattributes)
ab*	merge=filfre
abc	-foo -bar
*.c	frotz
----------------------------------------------------------------

the attributes given to path `t/abc` are computed as follows:

1. By examining `t/.gitattributes` (which is in the same
   diretory as the path in question), git finds that the first
   line matches.  `merge` attribute is set.  It also finds that
   the second line matches, and attributes `foo` and `bar`
   are unset.

2. Then it examines `.gitattributes` (which is in the parent
   directory), and finds that the first line matches, but
   `t/.gitattributes` file already decided how `merge`, `foo`
   and `bar` attributes should be given to this path, so it
   leaves `foo` and `bar` unset.  Attribute `baz` is set.

3. Finally it examines `$GIT_DIR/info/gitattributes`.  This file
   is used to override the in-tree settings.  The first line is
   a match, and `foo` is set, `bar` is reverted to unspecified
   state, and `baz` is unset.

As the result, the attributes assignement to `t/abc` becomes:

----------------------------------------------------------------
foo	set to true
bar	unspecified
baz	set to false
merge	set to string value "filfre"
frotz	unspecified
----------------------------------------------------------------


GIT
---
Part of the gitlink:git[7] suite

-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]