From: Junio C Hamano <junkio@cox.net>
To: git@vger.kernel.org
Subject: [RFR] gitattributes(5) documentation
Date: Thu, 19 Apr 2007 18:29:33 -0700 [thread overview]
Message-ID: <7vslav4yv6.fsf_-_@assigned-by-dhcp.cox.net> (raw)
In-Reply-To: <7v647tcjr6.fsf@assigned-by-dhcp.cox.net> (Junio C. Hamano's message of "Wed, 18 Apr 2007 17:04:13 -0700")
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
next prev parent reply other threads:[~2007-04-20 1:29 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-04-09 8:17 What's cooking in git.git (topics) Junio C Hamano
2007-04-16 1:53 ` Junio C Hamano
2007-04-19 0:04 ` Junio C Hamano
[not found] ` <7vslav4yv6.fsf_ -_@assigned-by-dhcp.cox.net>
2007-04-19 0:23 ` Alex Riesen
2007-04-19 2:39 ` Nicolas Pitre
2007-04-19 10:07 ` Martin Waitz
2007-04-20 11:14 ` Junio C Hamano
2007-04-20 11:58 ` Alex Riesen
2007-04-20 19:31 ` Sam Ravnborg
2007-04-21 6:09 ` Martin Waitz
2007-04-21 7:11 ` Linus Torvalds
2007-04-20 1:29 ` Junio C Hamano [this message]
2007-04-20 1:45 ` [RFR] gitattributes(5) documentation Linus Torvalds
2007-04-20 5:02 ` Junio C Hamano
2007-04-22 0:51 ` David Lang
2007-04-22 7:02 ` Junio C Hamano
2007-04-22 9:33 ` David Lang
2007-04-20 1:57 ` Nicolas Pitre
2007-04-22 6:24 ` What's cooking in git.git (topics) Junio C Hamano
2007-04-23 7:04 ` Junio C Hamano
2007-04-23 16:16 ` Nicolas Pitre
2007-04-23 17:07 ` Alex Riesen
2007-04-23 17:15 ` Junio C Hamano
2007-04-23 21:16 ` Alex Riesen
2007-04-23 21:51 ` Junio C Hamano
2007-04-24 15:58 ` Alex Riesen
2007-04-24 16:04 ` Johannes Schindelin
2007-04-24 16:14 ` Alex Riesen
2007-04-24 16:44 ` Johannes Schindelin
2007-04-24 21:41 ` Junio C Hamano
2007-04-25 8:11 ` Alex Riesen
2007-04-23 17:25 ` Johannes Schindelin
2007-04-27 8:24 ` Junio C Hamano
2007-04-29 18:33 ` Junio C Hamano
2007-04-29 18:45 ` Linus Torvalds
2007-04-30 23:20 ` Junio C Hamano
2007-05-06 8:53 ` Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=7vslav4yv6.fsf_-_@assigned-by-dhcp.cox.net \
--to=junkio@cox.net \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).