You can include one config file from another by setting the special
`include.path` variable to the name of the file to be included. The
+variable takes a pathname as its value, and is subject to tilde
+expansion.
+
+The
included file is expanded immediately, as if its contents had been
found at the location of the include directive. If the value of the
`include.path` variable is a relative path, the path is considered to be
relative to the configuration file in which the include directive was
-found. The value of `include.path` is subject to tilde expansion: `~/`
-is expanded to the value of `$HOME`, and `~user/` to the specified
-user's home directory. See below for examples.
+found. See below for examples.
+
Example
~~~~~~~
[include]
path = /path/to/foo.inc ; include by absolute path
path = foo ; expand "foo" relative to the current file
- path = ~/foo ; expand "foo" in your $HOME directory
+ path = ~/foo ; expand "foo" in your `$HOME` directory
Values
false;; Boolean false can be spelled as `no`, `off`,
`false`, or `0`.
+
-When converting value to the canonical form using '--bool' type
+When converting value to the canonical form using `--bool` type
specifier; 'git config' will ensure that the output is "true" or
"false" (spelled in lowercase).
1024", "by 1024x1024", etc.
color::
- The value for a variables that takes a color is a list of
- colors (at most two) and attributes (at most one), separated
- by spaces. The colors accepted are `normal`, `black`,
- `red`, `green`, `yellow`, `blue`, `magenta`, `cyan` and
- `white`; the attributes are `bold`, `dim`, `ul`, `blink` and
- `reverse`. The first color given is the foreground; the
- second is the background. The position of the attribute, if
- any, doesn't matter. Attributes may be turned off specifically
- by prefixing them with `no` (e.g., `noreverse`, `noul`, etc).
-+
-Colors (foreground and background) may also be given as numbers between
-0 and 255; these use ANSI 256-color mode (but note that not all
-terminals may support this). If your terminal supports it, you may also
-specify 24-bit RGB values as hex, like `#ff0ab3`.
-+
-The attributes are meant to be reset at the beginning of each item
-in the colored output, so setting color.decorate.branch to `black`
-will paint that branch name in a plain `black`, even if the previous
-thing on the same output line (e.g. opening parenthesis before the
-list of branch names in `log --decorate` output) is set to be
-painted with `bold` or some other attribute.
+ The value for a variable that takes a color is a list of
+ colors (at most two, one for foreground and one for background)
+ and attributes (as many as you want), separated by spaces.
++
+The basic colors accepted are `normal`, `black`, `red`, `green`, `yellow`,
+`blue`, `magenta`, `cyan` and `white`. The first color given is the
+foreground; the second is the background.
++
+Colors may also be given as numbers between 0 and 255; these use ANSI
+256-color mode (but note that not all terminals may support this). If
+your terminal supports it, you may also specify 24-bit RGB values as
+hex, like `#ff0ab3`.
++
+The accepted attributes are `bold`, `dim`, `ul`, `blink`, `reverse`,
+`italic`, and `strike` (for crossed-out or "strikethrough" letters).
+The position of any attributes with respect to the colors
+(before, after, or in between), doesn't matter. Specific attributes may
+be turned off by prefixing them with `no` or `no-` (e.g., `noreverse`,
+`no-ul`, etc).
++
+For git's pre-defined color slots, the attributes are meant to be reset
+at the beginning of each item in the colored output. So setting
+`color.decorate.branch` to `black` will paint that branch name in a
+plain `black`, even if the previous thing on the same output line (e.g.
+opening parenthesis before the list of branch names in `log --decorate`
+output) is set to be painted with `bold` or some other attribute.
+However, custom log formats may do more complicated and layered
+coloring, and the negated forms may be useful there.
+
+pathname::
+ A variable that takes a pathname value can be given a
+ string that begins with "`~/`" or "`~user/`", and the usual
+ tilde expansion happens to such a string: `~/`
+ is expanded to the value of `$HOME`, and `~user/` to the
+ specified user's home directory.
Variables
+
The default is true (when core.filemode is not specified in the config file).
+core.hideDotFiles::
+ (Windows-only) If true, mark newly-created directories and files whose
+ name starts with a dot as hidden. If 'dotGitOnly', only the `.git/`
+ directory is hidden, but no other files starting with a dot. The
+ default mode is 'dotGitOnly'.
+
core.ignoreCase::
If true, this option enables various workarounds to enable
Git to work better on filesystems that are not case sensitive,
mechanism.
core.autocrlf::
- Setting this variable to "true" is almost the same as setting
- the `text` attribute to "auto" on all files except that text
- files are not guaranteed to be normalized: files that contain
- `CRLF` in the repository will not be touched. Use this
- setting if you want to have `CRLF` line endings in your
- working directory even though the repository does not have
- normalized line endings. This variable can be set to 'input',
+ Setting this variable to "true" is the same as setting
+ the `text` attribute to "auto" on all files and core.eol to "crlf".
+ Set to true if you want to have `CRLF` line endings in your
+ working directory and the repository has LF line endings.
+ This variable can be set to 'input',
in which case no output conversion is performed.
core.symlinks::
may be set multiple times and is matched in the given order;
the first match wins.
+
-Can be overridden by the 'GIT_PROXY_COMMAND' environment variable
+Can be overridden by the `GIT_PROXY_COMMAND` environment variable
(which always applies universally, without the special "for"
handling).
+
This is useful for excluding servers inside a firewall from
proxy use, while defaulting to a common proxy for external domains.
+core.sshCommand::
+ If this variable is set, `git fetch` and `git push` will
+ use the specified command instead of `ssh` when they need to
+ connect to a remote system. The command is in the same form as
+ the `GIT_SSH_COMMAND` environment variable and is overridden
+ when the environment variable is set.
+
core.ignoreStat::
If true, Git will avoid using lstat() calls to detect if files have
changed by setting the "assume-unchanged" bit for those tracked files
core.worktree::
Set the path to the root of the working tree.
- If GIT_COMMON_DIR environment variable is set, core.worktree
+ If `GIT_COMMON_DIR` environment variable is set, core.worktree
is ignored and not used for determining the root of working tree.
- This can be overridden by the GIT_WORK_TREE environment
- variable and the '--work-tree' command-line option.
+ This can be overridden by the `GIT_WORK_TREE` environment
+ variable and the `--work-tree` command-line option.
The value can be an absolute path or relative to the path to
the .git directory, which is either specified by --git-dir
or GIT_DIR, or automatically discovered.
core.logAllRefUpdates::
Enable the reflog. Updates to a ref <ref> is logged to the file
- "$GIT_DIR/logs/<ref>", by appending the new and old
+ "`$GIT_DIR/logs/<ref>`", by appending the new and old
SHA-1, the date/time and the reason of the update, but
only when the file exists. If this configuration
- variable is set to true, missing "$GIT_DIR/logs/<ref>"
+ variable is set to true, missing "`$GIT_DIR/logs/<ref>`"
file is automatically created for branch heads (i.e. under
refs/heads/), remote refs (i.e. under refs/remotes/),
note refs (i.e. under refs/notes/), and the symbolic ref HEAD.
-1 is the zlib default. 0 means no compression,
and 1..9 are various speed/size tradeoffs, 9 being slowest.
If set, this provides a default to other compression variables,
- such as 'core.looseCompression' and 'pack.compression'.
+ such as `core.looseCompression` and `pack.compression`.
core.looseCompression::
An integer -1..9, indicating the compression level for objects that
Common unit suffixes of 'k', 'm', or 'g' are supported.
core.excludesFile::
- In addition to '.gitignore' (per-directory) and
- '.git/info/exclude', Git looks into this file for patterns
- of files which are not meant to be tracked. "`~/`" is expanded
- to the value of `$HOME` and "`~user/`" to the specified user's
- home directory. Its default value is $XDG_CONFIG_HOME/git/ignore.
- If $XDG_CONFIG_HOME is either not set or empty, $HOME/.config/git/ignore
+ Specifies the pathname to the file that contains patterns to
+ describe paths that are not meant to be tracked, in addition
+ to '.gitignore' (per-directory) and '.git/info/exclude'.
+ Defaults to `$XDG_CONFIG_HOME/git/ignore`.
+ If `$XDG_CONFIG_HOME` is either not set or empty, `$HOME/.config/git/ignore`
is used instead. See linkgit:gitignore[5].
core.askPass::
Some commands (e.g. svn and http interfaces) that interactively
ask for a password can be told to use an external program given
- via the value of this variable. Can be overridden by the 'GIT_ASKPASS'
+ via the value of this variable. Can be overridden by the `GIT_ASKPASS`
environment variable. If not set, fall back to the value of the
- 'SSH_ASKPASS' environment variable or, failing that, a simple password
+ `SSH_ASKPASS` environment variable or, failing that, a simple password
prompt. The external program shall be given a suitable prompt as
command-line argument and write the password on its STDOUT.
'.git/info/attributes', Git looks into this file for attributes
(see linkgit:gitattributes[5]). Path expansions are made the same
way as for `core.excludesFile`. Its default value is
- $XDG_CONFIG_HOME/git/attributes. If $XDG_CONFIG_HOME is either not
- set or empty, $HOME/.config/git/attributes is used instead.
+ `$XDG_CONFIG_HOME/git/attributes`. If `$XDG_CONFIG_HOME` is either not
+ set or empty, `$HOME/.config/git/attributes` is used instead.
+
+core.hooksPath::
+ By default Git will look for your hooks in the
+ '$GIT_DIR/hooks' directory. Set this to different path,
+ e.g. '/etc/git/hooks', and Git will try to find your hooks in
+ that directory, e.g. '/etc/git/hooks/pre-receive' instead of
+ in '$GIT_DIR/hooks/pre-receive'.
++
+The path can be either absolute or relative. A relative path is
+taken as relative to the directory where the hooks are run (see
+the "DESCRIPTION" section of linkgit:githooks[5]).
++
+This configuration variable is useful in cases where you'd like to
+centrally configure your Git hooks instead of configuring them on a
+per-repository basis, or as a more flexible and centralized
+alternative to having an `init.templateDir` where you've changed
+default hooks.
core.editor::
Commands such as `commit` and `tag` that lets you edit
notes should be printed.
+
This setting defaults to "refs/notes/commits", and it can be overridden by
-the 'GIT_NOTES_REF' environment variable. See linkgit:git-notes[1].
+the `GIT_NOTES_REF` environment variable. See linkgit:git-notes[1].
core.sparseCheckout::
Enable "sparse checkout" feature. See section "Sparse checkout" in
add.ignoreErrors::
add.ignore-errors (deprecated)::
Tells 'git add' to continue adding files when some files cannot be
- added due to indexing errors. Equivalent to the '--ignore-errors'
+ added due to indexing errors. Equivalent to the `--ignore-errors`
option of linkgit:git-add[1]. `add.ignore-errors` is deprecated,
as it does not follow the usual naming convention for configuration
variables.
"gitk --all --not ORIG_HEAD". Note that shell commands will be
executed from the top-level directory of a repository, which may
not necessarily be the current directory.
-'GIT_PREFIX' is set as returned by running 'git rev-parse --show-prefix'
+`GIT_PREFIX` is set as returned by running 'git rev-parse --show-prefix'
from the original current directory. See linkgit:git-rev-parse[1].
am.keepcr::
If true, git-am will call git-mailsplit for patches in mbox format
- with parameter '--keep-cr'. In this case git-mailsplit will
+ with parameter `--keep-cr`. In this case git-mailsplit will
not remove `\r` from lines ending with `\r\n`. Can be overridden
- by giving '--no-keep-cr' from the command line.
+ by giving `--no-keep-cr` from the command line.
See linkgit:git-am[1], linkgit:git-mailsplit[1].
am.threeWay::
apply.ignoreWhitespace::
When set to 'change', tells 'git apply' to ignore changes in
- whitespace, in the same way as the '--ignore-space-change'
+ whitespace, in the same way as the `--ignore-space-change`
option.
When set to one of: no, none, never, false tells 'git apply' to
respect all whitespace differences.
apply.whitespace::
Tells 'git apply' how to handle whitespaces, in the same way
- as the '--whitespace' option. See linkgit:git-apply[1].
+ as the `--whitespace` option. See linkgit:git-apply[1].
branch.autoSetupMerge::
Tells 'git branch' and 'git checkout' to set up new branches
browser.<tool>.path::
Override the path for the given tool that may be used to
- browse HTML help (see '-w' option in linkgit:git-help[1]) or a
+ browse HTML help (see `-w` option in linkgit:git-help[1]) or a
working repository in gitweb (see linkgit:git-instaweb[1]).
clean.requireForce::
message. Defaults to true.
commit.template::
- Specify a file to use as the template for new commit messages.
- "`~/`" is expanded to the value of `$HOME` and "`~user/`" to the
- specified user's home directory.
+ Specify the pathname of a file to use as the template for
+ new commit messages.
+
+commit.verbose::
+ A boolean or int to specify the level of verbose with `git commit`.
+ See linkgit:git-commit[1].
credential.helper::
Specify an external helper to be called when a username or
password credential is needed; the helper may consult external
- storage to avoid prompting the user for the credentials. See
- linkgit:gitcredentials[7] for details.
+ storage to avoid prompting the user for the credentials. Note
+ that multiple helpers may be defined. See linkgit:gitcredentials[7]
+ for details.
credential.useHttpPath::
When acquiring credentials, consider the "path" component of an http
difftool.prompt::
Prompt before each invocation of the diff tool.
+fastimport.unpackLimit::
+ If the number of objects imported by linkgit:git-fast-import[1]
+ is below this limit, then the objects will be unpacked into
+ loose object files. However if the number of imported objects
+ equals or exceeds this limit then the pack will be stored as a
+ pack. Storing the pack from a fast-import can make the import
+ operation complete faster, especially on slow filesystems. If
+ not set, the value of `transfer.unpackLimit` is used instead.
+
fetch.recurseSubmodules::
This option can be either set to a boolean value or to 'on-demand'.
Setting it to a boolean changes the behavior of fetch and pull to
If true, fetch will automatically behave as if the `--prune`
option was given on the command line. See also `remote.<name>.prune`.
+fetch.output::
+ Control how ref update status is printed. Valid values are
+ `full` and `compact`. Default value is `full`. See section
+ OUTPUT in linkgit:git-fetch[1] for detail.
+
format.attach::
Enable multipart/mixed attachments as the default for
'format-patch'. The value can also be a double quoted string
Set a custom directory to store the resulting files instead of the
current working directory.
+format.useAutoBase::
+ A boolean value which lets you enable the `--base=auto` option of
+ format-patch by default.
+
filter.<driver>.clean::
The command which is used to convert the content of a worktree
file to a blob upon checkin. See linkgit:gitattributes[5] for
'git worktree prune --expire 3.months.ago'.
This config variable can be used to set a different grace
period. The value "now" may be used to disable the grace
- period and prune $GIT_DIR/worktrees immediately, or "never"
+ period and prune `$GIT_DIR/worktrees` immediately, or "never"
may be used to suppress pruning.
gc.reflogExpire::
gitcvs.usecrlfattr::
If true, the server will look up the end-of-line conversion
- attributes for files to determine the '-k' modes to use. If
+ attributes for files to determine the `-k` modes to use. If
the attributes force Git to treat a file as text,
- the '-k' mode will be left blank so CVS clients will
+ the `-k` mode will be left blank so CVS clients will
treat it as text. If they suppress text conversion, the file
will be set with '-kb' mode, which suppresses any newline munging
the client might otherwise do. If the attributes do not allow
- the file type to be determined, then 'gitcvs.allBinary' is
+ the file type to be determined, then `gitcvs.allBinary` is
used. See linkgit:gitattributes[5].
gitcvs.allBinary::
- This is used if 'gitcvs.usecrlfattr' does not resolve
+ This is used if `gitcvs.usecrlfattr` does not resolve
the correct '-kb' mode to use. If true, all
unresolved files are sent to the client in
mode '-kb'. This causes the client to treat them
as binary files, which suppresses any newline munging it
otherwise might do. Alternatively, if it is set to "guess",
then the contents of the file are examined to decide if
- it is binary, similar to 'core.autocrlf'.
+ it is binary, similar to `core.autocrlf`.
gitcvs.dbName::
Database used by git-cvsserver to cache revision information
See linkgit:git-cvsserver[1].
gitcvs.dbUser, gitcvs.dbPass::
- Database user and password. Only useful if setting 'gitcvs.dbDriver',
+ Database user and password. Only useful if setting `gitcvs.dbDriver`,
since SQLite has no concept of database users and/or passwords.
'gitcvs.dbUser' supports variable substitution (see
linkgit:git-cvsserver[1] for details).
linkgit:git-cvsserver[1] for details). Any non-alphabetic
characters will be replaced with underscores.
-All gitcvs variables except for 'gitcvs.usecrlfattr' and
-'gitcvs.allBinary' can also be specified as
+All gitcvs variables except for `gitcvs.usecrlfattr` and
+`gitcvs.allBinary` can also be specified as
'gitcvs.<access_method>.<varname>' (where 'access_method'
is one of "ext" and "pserver") to make them apply only for the given
access method.
See linkgit:gitweb.conf[5] for description.
grep.lineNumber::
- If set to true, enable '-n' option by default.
+ If set to true, enable `-n` option by default.
grep.patternType::
Set the default matching behavior. Using a value of 'basic', 'extended',
- 'fixed', or 'perl' will enable the '--basic-regexp', '--extended-regexp',
- '--fixed-strings', or '--perl-regexp' option accordingly, while the
+ 'fixed', or 'perl' will enable the `--basic-regexp`, `--extended-regexp`,
+ `--fixed-strings`, or `--perl-regexp` option accordingly, while the
value 'default' will return to the default matching behavior.
grep.extendedRegexp::
- If set to true, enable '--extended-regexp' option by default. This
- option is ignored when the 'grep.patternType' option is set to a value
+ If set to true, enable `--extended-regexp` option by default. This
+ option is ignored when the `grep.patternType` option is set to a value
other than 'default'.
grep.threads::
is executed outside of a git repository. Defaults to false.
gpg.program::
- Use this custom program instead of "gpg" found on $PATH when
+ Use this custom program instead of "`gpg`" found on `$PATH` when
making or verifying a PGP signature. The program must support the
same command-line interface as GPG, namely, to verify a detached
- signature, "gpg --verify $file - <$signature" is run, and the
+ signature, "`gpg --verify $file - <$signature`" is run, and the
program is expected to signal a good signature by exiting with
code 0, and to generate an ASCII-armored detached signature, the
- standard input of "gpg -bsau $key" is fed with the contents to be
+ standard input of "`gpg -bsau $key`" is fed with the contents to be
signed, and the program is expected to send the result to its
standard output.
made by the linkgit:git-gui[1]. The default is "5".
gui.displayUntracked::
- Determines if linkgit::git-gui[1] shows untracked files
+ Determines if linkgit:git-gui[1] shows untracked files
in the file list. The default is "true".
gui.encoding::
of the linkgit:git-gui[1] `Tools` menu is invoked. This option is
mandatory for every tool. The command is executed from the root of
the working directory, and in the environment it receives the name of
- the tool as 'GIT_GUITOOL', the name of the currently selected file as
+ the tool as `GIT_GUITOOL`, the name of the currently selected file as
'FILENAME', and the name of the current branch as 'CUR_BRANCH' (if
the head is detached, 'CUR_BRANCH' is empty).
guitool.<name>.argPrompt::
Request a string argument from the user, and pass it to the tool
- through the 'ARGS' environment variable. Since requesting an
+ through the `ARGS` environment variable. Since requesting an
argument implies confirmation, the 'confirm' option has no effect
if this is enabled. If the option is set to 'true', 'yes', or '1',
the dialog uses a built-in generic prompt; otherwise the exact
guitool.<name>.revPrompt::
Request a single valid revision from the user, and set the
- 'REVISION' environment variable. In other aspects this option
+ `REVISION` environment variable. In other aspects this option
is similar to 'argPrompt', and can be used together with it.
guitool.<name>.revUnmerged::
only takes effect if the configured proxy string contains a user name part
(i.e. is of the form 'user@host' or 'user@host:port'). This can be
overridden on a per-remote basis; see `remote.<name>.proxyAuthMethod`.
- Both can be overridden by the 'GIT_HTTP_PROXY_AUTHMETHOD' environment
+ Both can be overridden by the `GIT_HTTP_PROXY_AUTHMETHOD` environment
variable. Possible values are:
+
--
a username in the URL, as libcurl normally requires a username for
authentication.
+http.extraHeader::
+ Pass an additional HTTP header when communicating with a server. If
+ more than one such entry exists, all of them are added as extra
+ headers. To allow overriding the settings inherited from the system
+ config, an empty value will reset the extra headers to the empty list.
+
http.cookieFile::
- File containing previously stored cookie lines which should be used
+ The pathname of a file containing previously stored cookie lines,
+ which should be used
in the Git http session, if they match the server. The file format
of the file to read cookies from should be plain HTTP headers or
- the Netscape/Mozilla cookie file format (see linkgit:curl[1]).
- NOTE that the file specified with http.cookieFile is only used as
+ the Netscape/Mozilla cookie file format (see `curl(1)`).
+ NOTE that the file specified with http.cookieFile is used only as
input unless http.saveCookies is set.
http.saveCookies::
- tlsv1.2
+
-Can be overridden by the 'GIT_SSL_VERSION' environment variable.
+Can be overridden by the `GIT_SSL_VERSION` environment variable.
To force git to use libcurl's default ssl version and ignore any
-explicit http.sslversion option, set 'GIT_SSL_VERSION' to the
+explicit http.sslversion option, set `GIT_SSL_VERSION` to the
empty string.
http.sslCipherList::
option; see the libcurl documentation for more details on the format
of this list.
+
-Can be overridden by the 'GIT_SSL_CIPHER_LIST' environment variable.
+Can be overridden by the `GIT_SSL_CIPHER_LIST` environment variable.
To force git to use libcurl's default cipher list and ignore any
-explicit http.sslCipherList option, set 'GIT_SSL_CIPHER_LIST' to the
+explicit http.sslCipherList option, set `GIT_SSL_CIPHER_LIST` to the
empty string.
http.sslVerify::
Whether to verify the SSL certificate when fetching or pushing
- over HTTPS. Can be overridden by the 'GIT_SSL_NO_VERIFY' environment
+ over HTTPS. Can be overridden by the `GIT_SSL_NO_VERIFY` environment
variable.
http.sslCert::
File containing the SSL certificate when fetching or pushing
- over HTTPS. Can be overridden by the 'GIT_SSL_CERT' environment
+ over HTTPS. Can be overridden by the `GIT_SSL_CERT` environment
variable.
http.sslKey::
File containing the SSL private key when fetching or pushing
- over HTTPS. Can be overridden by the 'GIT_SSL_KEY' environment
+ over HTTPS. Can be overridden by the `GIT_SSL_KEY` environment
variable.
http.sslCertPasswordProtected::
Enable Git's password prompt for the SSL certificate. Otherwise
OpenSSL will prompt the user, possibly many times, if the
certificate or private key is encrypted. Can be overridden by the
- 'GIT_SSL_CERT_PASSWORD_PROTECTED' environment variable.
+ `GIT_SSL_CERT_PASSWORD_PROTECTED` environment variable.
http.sslCAInfo::
File containing the certificates to verify the peer with when
fetching or pushing over HTTPS. Can be overridden by the
- 'GIT_SSL_CAINFO' environment variable.
+ `GIT_SSL_CAINFO` environment variable.
http.sslCAPath::
Path containing files with the CA certificates to verify the peer
with when fetching or pushing over HTTPS. Can be overridden
- by the 'GIT_SSL_CAPATH' environment variable.
+ by the `GIT_SSL_CAPATH` environment variable.
http.pinnedpubkey::
Public key of the https service. It may either be the filename of
http.maxRequests::
How many HTTP requests to launch in parallel. Can be overridden
- by the 'GIT_HTTP_MAX_REQUESTS' environment variable. Default is 5.
+ by the `GIT_HTTP_MAX_REQUESTS` environment variable. Default is 5.
http.minSessions::
The number of curl sessions (counted across slots) to be kept across
http.lowSpeedLimit, http.lowSpeedTime::
If the HTTP transfer speed is less than 'http.lowSpeedLimit'
for longer than 'http.lowSpeedTime' seconds, the transfer is aborted.
- Can be overridden by the 'GIT_HTTP_LOW_SPEED_LIMIT' and
- 'GIT_HTTP_LOW_SPEED_TIME' environment variables.
+ Can be overridden by the `GIT_HTTP_LOW_SPEED_LIMIT` and
+ `GIT_HTTP_LOW_SPEED_TIME` environment variables.
http.noEPSV::
A boolean which disables using of EPSV ftp command by curl.
This can helpful with some "poor" ftp servers which don't
- support EPSV mode. Can be overridden by the 'GIT_CURL_FTP_NO_EPSV'
+ support EPSV mode. Can be overridden by the `GIT_CURL_FTP_NO_EPSV`
environment variable. Default is false (curl will use EPSV).
http.userAgent::
such as Mozilla/4.0. This may be necessary, for instance, if
connecting through a firewall that restricts HTTP connections to a set
of common USER_AGENT strings (but not including those like git/1.7.1).
- Can be overridden by the 'GIT_HTTP_USER_AGENT' environment variable.
+ Can be overridden by the `GIT_HTTP_USER_AGENT` environment variable.
http.<url>.*::
Any of the http.* options above can be applied selectively to some URLs.
setting is silently ignored if portable keystroke input
is not available; requires the Perl module Term::ReadKey.
+interactive.diffFilter::
+ When an interactive command (such as `git add --patch`) shows
+ a colorized diff, git will pipe the diff through the shell
+ command defined by this configuration variable. The command may
+ mark up the diff further for human consumption, provided that it
+ retains a one-to-one correspondence with the lines in the
+ original diff. Defaults to disabled (no filtering).
+
log.abbrevCommit::
If true, makes linkgit:git-log[1], linkgit:git-show[1], and
linkgit:git-whatchanged[1] assume `--abbrev-commit`. You may
command. If 'short' is specified, the ref name prefixes 'refs/heads/',
'refs/tags/' and 'refs/remotes/' will not be printed. If 'full' is
specified, the full ref name (including prefix) will be printed.
- This is the same as the log commands '--decorate' option.
+ If 'auto' is specified, then if the output is going to a terminal,
+ the ref names are shown as if 'short' were given, otherwise no ref
+ names are shown. This is the same as the `--decorate` option
+ of the `git log`.
log.follow::
If `true`, `git log` will act as if the `--follow` option was used when
The maximum size of a pack. This setting only affects
packing to a file when repacking, i.e. the git:// protocol
is unaffected. It can be overridden by the `--max-pack-size`
- option of linkgit:git-repack[1]. The minimum size allowed is
- limited to 1 MiB. The default is unlimited.
+ option of linkgit:git-repack[1]. Reaching this limit results
+ in the creation of multiple packfiles; which in turn prevents
+ bitmaps from being created.
+ The minimum size allowed is limited to 1 MiB.
+ The default is unlimited.
Common unit suffixes of 'k', 'm', or 'g' are
supported.
--
push.followTags::
- If set to true enable '--follow-tags' option by default. You
+ If set to true enable `--follow-tags` option by default. You
may override this configuration at time of push by specifying
- '--no-follow-tags'.
+ `--no-follow-tags`.
push.gpgSign::
May be set to a boolean value, or the string 'if-asked'. A true
- value causes all pushes to be GPG signed, as if '--signed' is
+ value causes all pushes to be GPG signed, as if `--signed` is
passed to linkgit:git-push[1]. The string 'if-asked' causes
pushes to be signed if the server supports it, as if
- '--signed=if-asked' is passed to 'git push'. A false value may
+ `--signed=if-asked` is passed to 'git push'. A false value may
override a value from a lower-priority config file. An explicit
command-line flag always overrides this config option.
rebase. False by default.
rebase.autoSquash::
- If set to true enable '--autosquash' option by default.
+ If set to true enable `--autosquash` option by default.
rebase.autoStash::
When set to true, automatically create a temporary stash
objects to disk (e.g., when `git repack -a` is run). This
index can speed up the "counting objects" phase of subsequent
packs created for clones and fetches, at the cost of some disk
- space and extra time spent on the initial repack. Defaults to
- false.
+ space and extra time spent on the initial repack. This has
+ no effect if multiple packfiles are created.
+ Defaults to false.
rerere.autoUpdate::
When set to true, `git-rerere` updates the index with the
A configuration identity. When given, causes values in the
'sendemail.<identity>' subsection to take precedence over
values in the 'sendemail' section. The default identity is
- the value of 'sendemail.identity'.
+ the value of `sendemail.identity`.
sendemail.smtpEncryption::
See linkgit:git-send-email[1] for description. Note that this
Identity-specific versions of the 'sendemail.*' parameters
found below, taking precedence over those when the this
identity is selected, through command-line or
- 'sendemail.identity'.
+ `sendemail.identity`.
sendemail.aliasesFile::
sendemail.aliasFileType::
See linkgit:git-send-email[1] for description.
sendemail.signedoffcc (deprecated)::
- Deprecated alias for 'sendemail.signedoffbycc'.
+ Deprecated alias for `sendemail.signedoffbycc`.
showbranch.default::
The default set of branches for linkgit:git-show-branch[1].
"--ignore-submodules" option. The 'git submodule' commands are not
affected by this setting.
+submodule.fetchJobs::
+ Specifies how many submodules are fetched/cloned at the same time.
+ A positive integer allows up to that number of submodules fetched
+ in parallel. A value of 0 will give some reasonable default.
+ If unset, it defaults to 1.
+
+tag.forceSignAnnotated::
+ A boolean to specify whether annotated tags created should be GPG signed.
+ If `--annotate` is specified on the command line, it takes
+ precedence over this option.
+
tag.sort::
This variable controls the sort ordering of tags when displayed by
linkgit:git-tag[1]. Without the "--sort=<value>" option provided, the
`uploadpack.keepAlive` seconds. Setting this option to 0
disables keepalive packets entirely. The default is 5 seconds.
+uploadpack.packObjectsHook::
+ If this option is set, when `upload-pack` would run
+ `git pack-objects` to create a packfile for a client, it will
+ run this shell command instead. The `pack-objects` command and
+ arguments it _would_ have run (including the `git pack-objects`
+ at the beginning) are appended to the shell command. The stdin
+ and stdout of the hook are treated as if `pack-objects` itself
+ was run. I.e., `upload-pack` will feed input intended for
+ `pack-objects` to the hook, and expects a completed packfile on
+ stdout.
++
+Note that this configuration variable is ignored if it is seen in the
+repository-level config (this is a safety measure against fetching from
+untrusted repositories).
+
url.<base>.insteadOf::
Any URL that starts with this value will be rewritten to
start, instead, with <base>. In cases where some site serves a
user.email::
Your email address to be recorded in any newly created commits.
- Can be overridden by the 'GIT_AUTHOR_EMAIL', 'GIT_COMMITTER_EMAIL', and
- 'EMAIL' environment variables. See linkgit:git-commit-tree[1].
+ Can be overridden by the `GIT_AUTHOR_EMAIL`, `GIT_COMMITTER_EMAIL`, and
+ `EMAIL` environment variables. See linkgit:git-commit-tree[1].
user.name::
Your full name to be recorded in any newly created commits.
- Can be overridden by the 'GIT_AUTHOR_NAME' and 'GIT_COMMITTER_NAME'
+ Can be overridden by the `GIT_AUTHOR_NAME` and `GIT_COMMITTER_NAME`
environment variables. See linkgit:git-commit-tree[1].
user.useConfigOnly::
- Instruct Git to avoid trying to guess defaults for 'user.email'
- and 'user.name', and instead retrieve the values only from the
+ Instruct Git to avoid trying to guess defaults for `user.email`
+ and `user.name`, and instead retrieve the values only from the
configuration. For example, if you have multiple email addresses
and would like to use a different one for each repository, then
with this configuration option set to `true` in the global config
repository. To control what line ending style is used in the working
directory, use the `eol` attribute for a single file and the
`core.eol` configuration variable for all text files.
+ Note that `core.autocrlf` overrides `core.eol`
Set::
Set to string value "auto"::
When `text` is set to "auto", the path is marked for automatic
- end-of-line normalization. If Git decides that the content is
- text, its line endings are normalized to LF on checkin.
+ end-of-line conversion. If Git decides that the content is
+ text, its line endings are converted to LF on checkin.
+ When the file has been commited with CRLF, no conversion is done.
Unspecified::
^^^^^
This attribute sets a specific line-ending style to be used in the
- working directory. It enables end-of-line normalization without any
+ working directory. It enables end-of-line conversion without any
content checks, effectively setting the `text` attribute.
Set to string value "crlf"::
regardless of their content.
------------------------
+ * text=auto
*.txt text
- *.vcproj eol=crlf
- *.sh eol=lf
+ *.vcproj text eol=crlf
+ *.sh text eol=lf
*.jpg -text
------------------------
If you simply want to have CRLF line endings in your working directory
regardless of the repository you are working with, you can set the
- config variable "core.autocrlf" without changing any attributes.
+ config variable "core.autocrlf" without using any attributes.
------------------------
[core]
- `csharp` suitable for source code in the C# language.
+- `css` suitable for cascading style sheets.
+
- `fortran` suitable for source code in the Fortran language.
- `fountain` suitable for Fountain documents.
#define rename_cache_entry_at(pos, new_name) rename_index_entry_at(&the_index, (pos), (new_name))
#define remove_cache_entry_at(pos) remove_index_entry_at(&the_index, (pos))
#define remove_file_from_cache(path) remove_file_from_index(&the_index, (path))
-#define add_to_cache(path, st, flags) add_to_index(&the_index, (path), (st), (flags))
-#define add_file_to_cache(path, flags) add_file_to_index(&the_index, (path), (flags))
+#define add_to_cache(path, st, flags) add_to_index(&the_index, (path), (st), (flags), 0)
+#define add_file_to_cache(path, flags) add_file_to_index(&the_index, (path), (flags), 0)
#define refresh_cache(flags) refresh_index(&the_index, (flags), NULL, NULL, NULL)
#define ce_match_stat(ce, st, options) ie_match_stat(&the_index, (ce), (st), (options))
#define ce_modified(ce, st, options) ie_modified(&the_index, (ce), (st), (options))
#define ADD_CACHE_IGNORE_ERRORS 4
#define ADD_CACHE_IGNORE_REMOVAL 8
#define ADD_CACHE_INTENT 16
-extern int add_to_index(struct index_state *, const char *path, struct stat *, int flags);
-extern int add_file_to_index(struct index_state *, const char *path, int flags);
+extern int add_to_index(struct index_state *, const char *path, struct stat *, int flags, int force_mode);
+extern int add_file_to_index(struct index_state *, const char *path, int flags, int force_mode);
extern struct cache_entry *make_cache_entry(unsigned int mode, const unsigned char *sha1, const char *path, int stage, unsigned int refresh_options);
extern int ce_same_name(const struct cache_entry *a, const struct cache_entry *b);
extern void set_object_name_for_intent_to_add_entry(struct cache_entry *ce);
#define REFRESH_IGNORE_SUBMODULES 0x0010 /* ignore submodules */
#define REFRESH_IN_PORCELAIN 0x0020 /* user friendly output, not "needs update" */
extern int refresh_index(struct index_state *, unsigned int flags, const struct pathspec *pathspec, char *seen, const char *header_msg);
+ extern struct cache_entry *refresh_cache_entry(struct cache_entry *, unsigned int);
extern void update_index_if_able(struct index_state *, struct lock_file *);
extern int log_all_ref_updates;
extern int warn_ambiguous_refs;
extern int warn_on_object_refname_ambiguity;
-extern int shared_repository;
extern const char *apply_default_whitespace;
extern const char *apply_default_ignorewhitespace;
extern const char *git_attributes_file;
+extern const char *git_hooks_path;
extern int zlib_compression_level;
extern int core_compression_level;
extern int core_compression_seen;
extern unsigned long big_file_threshold;
extern unsigned long pack_size_limit_cfg;
+void set_shared_repository(int value);
+int get_shared_repository(void);
+
/*
* Do replace refs need to be checked this run? This variable is
* initialized to true unless --no-replace-object is used or
extern char comment_line_char;
extern int auto_comment_line_char;
+/* Windows only */
+enum hide_dotfiles_type {
+ HIDE_DOTFILES_FALSE = 0,
+ HIDE_DOTFILES_TRUE,
+ HIDE_DOTFILES_DOTGITONLY
+};
+extern enum hide_dotfiles_type hide_dotfiles;
+
enum branch_track {
BRANCH_TRACK_UNSPECIFIED = -1,
BRANCH_TRACK_NEVER = 0,
*/
#define GIT_REPO_VERSION 0
#define GIT_REPO_VERSION_READ 1
-extern int repository_format_version;
extern int repository_format_precious_objects;
-extern int check_repository_format(void);
+
+struct repository_format {
+ int version;
+ int precious_objects;
+ int is_bare;
+ char *work_tree;
+ struct string_list unknown_extensions;
+};
+
+/*
+ * Read the repository format characteristics from the config file "path" into
+ * "format" struct. Returns the numeric version. On error, -1 is returned,
+ * format->version is set to -1, and all other fields in the struct are
+ * undefined.
+ */
+int read_repository_format(struct repository_format *format, const char *path);
+
+/*
+ * Verify that the repository described by repository_format is something we
+ * can read. If it is, return 0. Otherwise, return -1, and "err" will describe
+ * any errors encountered.
+ */
+int verify_repository_format(const struct repository_format *format,
+ struct strbuf *err);
+
+/*
+ * Check the repository format version in the path found in get_git_dir(),
+ * and die if it is a version we don't understand. Generally one would
+ * set_git_dir() before calling this, and use it only for "are we in a valid
+ * repo?".
+ */
+extern void check_repository_format(void);
#define MTIME_CHANGED 0x0001
#define CTIME_CHANGED 0x0002
*/
extern const char *mkpath(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
extern const char *git_path(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
+extern const char *git_common_path(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
extern char *mksnpath(char *buf, size_t n, const char *fmt, ...)
__attribute__((format (printf, 3, 4)));
extern void strbuf_git_path(struct strbuf *sb, const char *fmt, ...)
__attribute__((format (printf, 2, 3)));
+extern void strbuf_git_common_path(struct strbuf *sb, const char *fmt, ...)
+ __attribute__((format (printf, 2, 3)));
extern char *git_path_buf(struct strbuf *buf, const char *fmt, ...)
__attribute__((format (printf, 2, 3)));
extern void strbuf_git_path_submodule(struct strbuf *sb, const char *path,
int git_mkstemp(char *path, size_t n, const char *template);
-int git_mkstemps(char *path, size_t n, const char *template, int suffix_len);
-
/* set default permissions by passing mode arguments to open(2) */
int git_mkstemps_mode(char *pattern, int suffix_len, int mode);
int git_mkstemp_mode(char *pattern, int mode);
* directory while we were working. To be robust against this kind of
* race, callers might want to try invoking the function again when it
* returns SCLD_VANISHED.
+ *
+ * safe_create_leading_directories() temporarily changes path while it
+ * is working but restores it before returning.
+ * safe_create_leading_directories_const() doesn't modify path, even
+ * temporarily.
*/
enum scld_error {
SCLD_OK = 0,
extern void maybe_die_on_misspelt_object_name(const char *name, const char *prefix);
extern int get_sha1_with_context(const char *str, unsigned flags, unsigned char *sha1, struct object_context *orc);
+extern int get_oid(const char *str, struct object_id *oid);
+
typedef int each_abbrev_fn(const unsigned char *sha1, void *);
extern int for_each_abbrev(const char *prefix, each_abbrev_fn, void *);
* printf("%s -> %s", sha1_to_hex(one), sha1_to_hex(two));
*/
extern char *sha1_to_hex_r(char *out, const unsigned char *sha1);
+extern char *oid_to_hex_r(char *out, const struct object_id *oid);
extern char *sha1_to_hex(const unsigned char *sha1); /* static buffer result! */
extern char *oid_to_hex(const struct object_id *oid); /* same static buffer as sha1_to_hex */
extern int git_config_with_options(config_fn_t fn, void *,
struct git_config_source *config_source,
int respect_includes);
-extern int git_config_early(config_fn_t fn, void *, const char *repo_config);
extern int git_parse_ulong(const char *, unsigned long *);
extern int git_parse_maybe_bool(const char *);
extern int git_config_int(const char *, const char *);
extern int git_config_rename_section(const char *, const char *);
extern int git_config_rename_section_in_file(const char *, const char *, const char *);
extern const char *git_etc_gitconfig(void);
-extern int check_repository_format_version(const char *var, const char *value, void *cb);
extern int git_env_bool(const char *, int);
extern unsigned long git_env_ulong(const char *, unsigned long);
extern int git_config_system(void);
extern const char *get_commit_output_encoding(void);
extern int git_config_parse_parameter(const char *, config_fn_t fn, void *data);
+
+enum config_scope {
+ CONFIG_SCOPE_UNKNOWN = 0,
+ CONFIG_SCOPE_SYSTEM,
+ CONFIG_SCOPE_GLOBAL,
+ CONFIG_SCOPE_REPO,
+ CONFIG_SCOPE_CMDLINE,
+};
+
+extern enum config_scope current_config_scope(void);
extern const char *current_config_origin_type(void);
extern const char *current_config_name(void);
struct key_value_info {
const char *filename;
int linenr;
+ const char *origin_type;
+ enum config_scope scope;
};
extern NORETURN void git_die_config(const char *key, const char *err, ...) __attribute__((format(printf, 2, 3)));
extern int copy_file_with_time(const char *dst, const char *src, int mode);
extern void write_or_die(int fd, const void *buf, size_t count);
-extern int write_or_whine(int fd, const void *buf, size_t count, const char *msg);
extern int write_or_whine_pipe(int fd, const void *buf, size_t count, const char *msg);
extern void fsync_or_die(int fd, const char *);
return write_in_full(fd, str, strlen(str));
}
-extern int write_file(const char *path, const char *fmt, ...);
-extern int write_file_gently(const char *path, const char *fmt, ...);
+/**
+ * Open (and truncate) the file at path, write the contents of buf to it,
+ * and close it. Dies if any errors are encountered.
+ */
+extern void write_file_buf(const char *path, const char *buf, size_t len);
+
+/**
+ * Like write_file_buf(), but format the contents into a buffer first.
+ * Additionally, write_file() will append a newline if one is not already
+ * present, making it convenient to write text files:
+ *
+ * write_file(path, "counter: %d", ctr);
+ */
+__attribute__((format (printf, 2, 3)))
+extern void write_file(const char *path, const char *fmt, ...);
/* pager.c */
extern void setup_pager(void);
* return 0 if success, 1 - if addition of a file failed and
* ADD_FILES_IGNORE_ERRORS was specified in flags
*/
-int add_files_to_cache(const char *prefix, const struct pathspec *pathspec, int flags);
+int add_files_to_cache(const char *prefix, const struct pathspec *pathspec, int flags, int force_mode);
/* diff.c */
extern int diff_auto_refresh_index;
/* match-trees.c */
-void shift_tree(const unsigned char *, const unsigned char *, unsigned char *, int);
-void shift_tree_by(const unsigned char *, const unsigned char *, unsigned char *, const char *);
+void shift_tree(const struct object_id *, const struct object_id *, struct object_id *, int);
+void shift_tree_by(const struct object_id *, const struct object_id *, struct object_id *, const char *);
/*
* whitespace rules.
/* Takes a negative value returned by split_cmdline */
const char *split_cmdline_strerror(int cmdline_errno);
-/* git.c */
+/* setup.c */
struct startup_info {
int have_repository;
const char *prefix;
struct object_id shifted;
if (!*subtree_shift) {
- shift_tree(one->object.oid.hash, two->object.oid.hash, shifted.hash, 0);
+ shift_tree(&one->object.oid, &two->object.oid, &shifted, 0);
} else {
- shift_tree_by(one->object.oid.hash, two->object.oid.hash, shifted.hash,
+ shift_tree_by(&one->object.oid, &two->object.oid, &shifted,
subtree_shift);
}
if (!oidcmp(&two->object.oid, &shifted))
* Since we use get_tree_entry(), which does not put the read object into
* the object pool, we cannot rely on a == b.
*/
-static int sha_eq(const unsigned char *a, const unsigned char *b)
+static int oid_eq(const struct object_id *a, const struct object_id *b)
{
if (!a && !b)
return 2;
- return a && b && hashcmp(a, b) == 0;
+ return a && b && oidcmp(a, b) == 0;
}
enum rename_type {
struct stage_data {
struct {
unsigned mode;
- unsigned char sha[20];
+ struct object_id oid;
} stages[4];
struct rename_conflict_info *rename_conflict_info;
unsigned processed:1;
int ostage2 = ostage1 ^ 1;
ci->ren1_other.path = pair1->one->path;
- hashcpy(ci->ren1_other.sha1, src_entry1->stages[ostage1].sha);
+ oidcpy(&ci->ren1_other.oid, &src_entry1->stages[ostage1].oid);
ci->ren1_other.mode = src_entry1->stages[ostage1].mode;
ci->ren2_other.path = pair2->one->path;
- hashcpy(ci->ren2_other.sha1, src_entry2->stages[ostage2].sha);
+ oidcpy(&ci->ren2_other.oid, &src_entry2->stages[ostage2].oid);
ci->ren2_other.mode = src_entry2->stages[ostage2].mode;
}
}
}
}
-static int add_cacheinfo(unsigned int mode, const unsigned char *sha1,
+static int add_cacheinfo(unsigned int mode, const struct object_id *oid,
const char *path, int stage, int refresh, int options)
{
struct cache_entry *ce;
- ce = make_cache_entry(mode, oid ? oid->hash : null_sha1, path, stage,
- (refresh ? (CE_MATCH_REFRESH |
- CE_MATCH_IGNORE_MISSING) : 0 ));
+ int ret;
+
- ce = make_cache_entry(mode, sha1 ? sha1 : null_sha1, path, stage, 0);
++ ce = make_cache_entry(mode, oid ? oid->hash : null_sha1, path, stage, 0);
if (!ce)
return error(_("addinfo_cache failed for path '%s'"), path);
- return add_cache_entry(ce, options);
+
+ ret = add_cache_entry(ce, options);
+ if (refresh) {
+ struct cache_entry *nce;
+
+ nce = refresh_cache_entry(ce, CE_MATCH_REFRESH | CE_MATCH_IGNORE_MISSING);
+ if (nce != ce)
+ ret = add_cache_entry(nce, options);
+ }
+ return ret;
}
static void init_tree_desc_from_tree(struct tree_desc *desc, struct tree *tree)
struct string_list_item *item;
struct stage_data *e = xcalloc(1, sizeof(struct stage_data));
get_tree_entry(o->object.oid.hash, path,
- e->stages[1].sha, &e->stages[1].mode);
+ e->stages[1].oid.hash, &e->stages[1].mode);
get_tree_entry(a->object.oid.hash, path,
- e->stages[2].sha, &e->stages[2].mode);
+ e->stages[2].oid.hash, &e->stages[2].mode);
get_tree_entry(b->object.oid.hash, path,
- e->stages[3].sha, &e->stages[3].mode);
+ e->stages[3].oid.hash, &e->stages[3].mode);
item = string_list_insert(entries, path);
item->util = e;
return e;
}
e = item->util;
e->stages[ce_stage(ce)].mode = ce->ce_mode;
- hashcpy(e->stages[ce_stage(ce)].sha, ce->sha1);
+ hashcpy(e->stages[ce_stage(ce)].oid.hash, ce->sha1);
}
return unmerged;
if (remove_file_from_cache(path))
return -1;
if (o)
- if (add_cacheinfo(o->mode, o->sha1, path, 1, 0, options))
+ if (add_cacheinfo(o->mode, &o->oid, path, 1, 0, options))
return -1;
if (a)
- if (add_cacheinfo(a->mode, a->sha1, path, 2, 0, options))
+ if (add_cacheinfo(a->mode, &a->oid, path, 2, 0, options))
return -1;
if (b)
- if (add_cacheinfo(b->mode, b->sha1, path, 3, 0, options))
+ if (add_cacheinfo(b->mode, &b->oid, path, 3, 0, options))
return -1;
return 0;
}
entry->stages[1].mode = o->mode;
entry->stages[2].mode = a->mode;
entry->stages[3].mode = b->mode;
- hashcpy(entry->stages[1].sha, o->sha1);
- hashcpy(entry->stages[2].sha, a->sha1);
- hashcpy(entry->stages[3].sha, b->sha1);
+ oidcpy(&entry->stages[1].oid, &o->oid);
+ oidcpy(&entry->stages[2].oid, &a->oid);
+ oidcpy(&entry->stages[3].oid, &b->oid);
}
static int remove_file(struct merge_options *o, int clean,
base_len = newpath.len;
while (string_list_has_string(&o->current_file_set, newpath.buf) ||
string_list_has_string(&o->current_directory_set, newpath.buf) ||
- file_exists(newpath.buf)) {
+ (!o->call_depth && file_exists(newpath.buf))) {
strbuf_setlen(&newpath, base_len);
strbuf_addf(&newpath, "_%d", suffix++);
}
}
static void update_file_flags(struct merge_options *o,
- const unsigned char *sha,
+ const struct object_id *oid,
unsigned mode,
const char *path,
int update_cache,
goto update_index;
}
- buf = read_sha1_file(sha, &type, &size);
+ buf = read_sha1_file(oid->hash, &type, &size);
if (!buf)
- die(_("cannot read object %s '%s'"), sha1_to_hex(sha), path);
+ die(_("cannot read object %s '%s'"), oid_to_hex(oid), path);
if (type != OBJ_BLOB)
- die(_("blob expected for %s '%s'"), sha1_to_hex(sha), path);
+ die(_("blob expected for %s '%s'"), oid_to_hex(oid), path);
if (S_ISREG(mode)) {
struct strbuf strbuf = STRBUF_INIT;
if (convert_to_working_tree(path, buf, size, &strbuf)) {
free(lnk);
} else
die(_("do not know what to do with %06o %s '%s'"),
- mode, sha1_to_hex(sha), path);
+ mode, oid_to_hex(oid), path);
free(buf);
}
update_index:
if (update_cache)
- add_cacheinfo(mode, sha, path, 0, update_wd, ADD_CACHE_OK_TO_ADD);
+ add_cacheinfo(mode, oid, path, 0, update_wd, ADD_CACHE_OK_TO_ADD);
}
static void update_file(struct merge_options *o,
int clean,
- const unsigned char *sha,
+ const struct object_id *oid,
unsigned mode,
const char *path)
{
- update_file_flags(o, sha, mode, path, o->call_depth || clean, !o->call_depth);
+ update_file_flags(o, oid, mode, path, o->call_depth || clean, !o->call_depth);
}
/* Low level file merging, update and removal */
struct merge_file_info {
- unsigned char sha[20];
+ struct object_id oid;
unsigned mode;
unsigned clean:1,
merge:1;
name2 = mkpathdup("%s", branch2);
}
- read_mmblob(&orig, one->sha1);
- read_mmblob(&src1, a->sha1);
- read_mmblob(&src2, b->sha1);
+ read_mmblob(&orig, one->oid.hash);
+ read_mmblob(&src1, a->oid.hash);
+ read_mmblob(&src2, b->oid.hash);
merge_status = ll_merge(result_buf, a->path, &orig, base_name,
&src1, name1, &src2, name2, &ll_opts);
result.clean = 0;
if (S_ISREG(a->mode)) {
result.mode = a->mode;
- hashcpy(result.sha, a->sha1);
+ oidcpy(&result.oid, &a->oid);
} else {
result.mode = b->mode;
- hashcpy(result.sha, b->sha1);
+ oidcpy(&result.oid, &b->oid);
}
} else {
- if (!sha_eq(a->sha1, one->sha1) && !sha_eq(b->sha1, one->sha1))
+ if (!oid_eq(&a->oid, &one->oid) && !oid_eq(&b->oid, &one->oid))
result.merge = 1;
/*
}
}
- if (sha_eq(a->sha1, b->sha1) || sha_eq(a->sha1, one->sha1))
- hashcpy(result.sha, b->sha1);
- else if (sha_eq(b->sha1, one->sha1))
- hashcpy(result.sha, a->sha1);
+ if (oid_eq(&a->oid, &b->oid) || oid_eq(&a->oid, &one->oid))
+ oidcpy(&result.oid, &b->oid);
+ else if (oid_eq(&b->oid, &one->oid))
+ oidcpy(&result.oid, &a->oid);
else if (S_ISREG(a->mode)) {
mmbuffer_t result_buf;
int merge_status;
die(_("Failed to execute internal merge"));
if (write_sha1_file(result_buf.ptr, result_buf.size,
- blob_type, result.sha))
+ blob_type, result.oid.hash))
die(_("Unable to add %s to database"),
a->path);
free(result_buf.ptr);
result.clean = (merge_status == 0);
} else if (S_ISGITLINK(a->mode)) {
- result.clean = merge_submodule(result.sha,
- one->path, one->sha1,
- a->sha1, b->sha1,
+ result.clean = merge_submodule(result.oid.hash,
+ one->path,
+ one->oid.hash,
+ a->oid.hash,
+ b->oid.hash,
!o->call_depth);
} else if (S_ISLNK(a->mode)) {
- hashcpy(result.sha, a->sha1);
+ oidcpy(&result.oid, &a->oid);
- if (!sha_eq(a->sha1, b->sha1))
+ if (!oid_eq(&a->oid, &b->oid))
result.clean = 0;
} else {
die(_("unsupported object type in the tree"));
static struct merge_file_info merge_file_one(struct merge_options *o,
const char *path,
- const unsigned char *o_sha, int o_mode,
- const unsigned char *a_sha, int a_mode,
- const unsigned char *b_sha, int b_mode,
+ const struct object_id *o_oid, int o_mode,
+ const struct object_id *a_oid, int a_mode,
+ const struct object_id *b_oid, int b_mode,
const char *branch1,
const char *branch2)
{
struct diff_filespec one, a, b;
one.path = a.path = b.path = (char *)path;
- hashcpy(one.sha1, o_sha);
+ oidcpy(&one.oid, o_oid);
one.mode = o_mode;
- hashcpy(a.sha1, a_sha);
+ oidcpy(&a.oid, a_oid);
a.mode = a_mode;
- hashcpy(b.sha1, b_sha);
+ oidcpy(&b.oid, b_oid);
b.mode = b_mode;
return merge_file_1(o, &one, &a, &b, branch1, branch2);
}
static void handle_change_delete(struct merge_options *o,
const char *path,
- const unsigned char *o_sha, int o_mode,
- const unsigned char *a_sha, int a_mode,
- const unsigned char *b_sha, int b_mode,
+ const struct object_id *o_oid, int o_mode,
+ const struct object_id *a_oid, int a_mode,
+ const struct object_id *b_oid, int b_mode,
const char *change, const char *change_past)
{
char *renamed = NULL;
if (dir_in_way(path, !o->call_depth)) {
- renamed = unique_path(o, path, a_sha ? o->branch1 : o->branch2);
+ renamed = unique_path(o, path, a_oid ? o->branch1 : o->branch2);
}
if (o->call_depth) {
* them, simply reuse the base version for virtual merge base.
*/
remove_file_from_cache(path);
- update_file(o, 0, o_sha, o_mode, renamed ? renamed : path);
- } else if (!a_sha) {
+ update_file(o, 0, o_oid, o_mode, renamed ? renamed : path);
+ } else if (!a_oid) {
if (!renamed) {
output(o, 1, _("CONFLICT (%s/delete): %s deleted in %s "
"and %s in %s. Version %s of %s left in tree."),
change, path, o->branch1, change_past,
o->branch2, o->branch2, path);
- update_file(o, 0, b_sha, b_mode, path);
+ update_file(o, 0, b_oid, b_mode, path);
} else {
output(o, 1, _("CONFLICT (%s/delete): %s deleted in %s "
"and %s in %s. Version %s of %s left in tree at %s."),
change, path, o->branch1, change_past,
o->branch2, o->branch2, path, renamed);
- update_file(o, 0, b_sha, b_mode, renamed);
+ update_file(o, 0, b_oid, b_mode, renamed);
}
} else {
if (!renamed) {
"and %s in %s. Version %s of %s left in tree at %s."),
change, path, o->branch2, change_past,
o->branch1, o->branch1, path, renamed);
- update_file(o, 0, a_sha, a_mode, renamed);
+ update_file(o, 0, a_oid, a_mode, renamed);
}
/*
* No need to call update_file() on path when !renamed, since
{
const struct diff_filespec *orig = pair->one;
const struct diff_filespec *dest = pair->two;
- const unsigned char *a_sha = NULL;
- const unsigned char *b_sha = NULL;
+ const struct object_id *a_oid = NULL;
+ const struct object_id *b_oid = NULL;
int a_mode = 0;
int b_mode = 0;
if (rename_branch == o->branch1) {
- a_sha = dest->sha1;
+ a_oid = &dest->oid;
a_mode = dest->mode;
} else {
- b_sha = dest->sha1;
+ b_oid = &dest->oid;
b_mode = dest->mode;
}
handle_change_delete(o,
o->call_depth ? orig->path : dest->path,
- orig->sha1, orig->mode,
- a_sha, a_mode,
- b_sha, b_mode,
+ &orig->oid, orig->mode,
+ a_oid, a_mode,
+ b_oid, b_mode,
_("rename"), _("renamed"));
if (o->call_depth) {
struct stage_data *entry,
int stage)
{
- unsigned char *sha = entry->stages[stage].sha;
+ struct object_id *oid = &entry->stages[stage].oid;
unsigned mode = entry->stages[stage].mode;
- if (mode == 0 || is_null_sha1(sha))
+ if (mode == 0 || is_null_oid(oid))
return NULL;
- hashcpy(target->sha1, sha);
+ oidcpy(&target->oid, oid);
target->mode = mode;
return target;
}
add = filespec_from_entry(&other, dst_entry, stage ^ 1);
if (add) {
char *add_name = unique_path(o, rename->path, other_branch);
- update_file(o, 0, add->sha1, add->mode, add_name);
+ update_file(o, 0, &add->oid, add->mode, add_name);
remove_file(o, 0, rename->path, 0);
dst_name = unique_path(o, rename->path, cur_branch);
rename->path, other_branch, dst_name);
}
}
- update_file(o, 0, rename->sha1, rename->mode, dst_name);
+ update_file(o, 0, &rename->oid, rename->mode, dst_name);
if (stage == 2)
update_stages(rename->path, NULL, rename, add);
else
struct diff_filespec other;
struct diff_filespec *add;
mfi = merge_file_one(o, one->path,
- one->sha1, one->mode,
- a->sha1, a->mode,
- b->sha1, b->mode,
+ &one->oid, one->mode,
+ &a->oid, a->mode,
+ &b->oid, b->mode,
ci->branch1, ci->branch2);
/*
* FIXME: For rename/add-source conflicts (if we could detect
* pathname and then either rename the add-source file to that
* unique path, or use that unique path instead of src here.
*/
- update_file(o, 0, mfi.sha, mfi.mode, one->path);
+ update_file(o, 0, &mfi.oid, mfi.mode, one->path);
/*
* Above, we put the merged content at the merge-base's
*/
add = filespec_from_entry(&other, ci->dst_entry1, 2 ^ 1);
if (add)
- update_file(o, 0, add->sha1, add->mode, a->path);
+ update_file(o, 0, &add->oid, add->mode, a->path);
else
remove_file_from_cache(a->path);
add = filespec_from_entry(&other, ci->dst_entry2, 3 ^ 1);
if (add)
- update_file(o, 0, add->sha1, add->mode, b->path);
+ update_file(o, 0, &add->oid, add->mode, b->path);
else
remove_file_from_cache(b->path);
} else {
a->path, c1->path, ci->branch1,
b->path, c2->path, ci->branch2);
- remove_file(o, 1, a->path, would_lose_untracked(a->path));
- remove_file(o, 1, b->path, would_lose_untracked(b->path));
+ remove_file(o, 1, a->path, o->call_depth || would_lose_untracked(a->path));
+ remove_file(o, 1, b->path, o->call_depth || would_lose_untracked(b->path));
mfi_c1 = merge_file_special_markers(o, a, c1, &ci->ren1_other,
o->branch1, c1->path,
* again later for the non-recursive merge.
*/
remove_file(o, 0, path, 0);
- update_file(o, 0, mfi_c1.sha, mfi_c1.mode, a->path);
- update_file(o, 0, mfi_c2.sha, mfi_c2.mode, b->path);
+ update_file(o, 0, &mfi_c1.oid, mfi_c1.mode, a->path);
+ update_file(o, 0, &mfi_c2.oid, mfi_c2.mode, b->path);
} else {
char *new_path1 = unique_path(o, path, ci->branch1);
char *new_path2 = unique_path(o, path, ci->branch2);
output(o, 1, _("Renaming %s to %s and %s to %s instead"),
a->path, new_path1, b->path, new_path2);
remove_file(o, 0, path, 0);
- update_file(o, 0, mfi_c1.sha, mfi_c1.mode, new_path1);
- update_file(o, 0, mfi_c2.sha, mfi_c2.mode, new_path2);
+ update_file(o, 0, &mfi_c1.oid, mfi_c1.mode, new_path1);
+ update_file(o, 0, &mfi_c2.oid, mfi_c2.mode, new_path2);
free(new_path2);
free(new_path1);
}
remove_file(o, 1, ren1_src,
renamed_stage == 2 || !was_tracked(ren1_src));
- hashcpy(src_other.sha1, ren1->src_entry->stages[other_stage].sha);
+ oidcpy(&src_other.oid,
+ &ren1->src_entry->stages[other_stage].oid);
src_other.mode = ren1->src_entry->stages[other_stage].mode;
- hashcpy(dst_other.sha1, ren1->dst_entry->stages[other_stage].sha);
+ oidcpy(&dst_other.oid,
+ &ren1->dst_entry->stages[other_stage].oid);
dst_other.mode = ren1->dst_entry->stages[other_stage].mode;
try_merge = 0;
- if (sha_eq(src_other.sha1, null_sha1)) {
+ if (oid_eq(&src_other.oid, &null_oid)) {
setup_rename_conflict_info(RENAME_DELETE,
ren1->pair,
NULL,
NULL,
NULL);
} else if ((dst_other.mode == ren1->pair->two->mode) &&
- sha_eq(dst_other.sha1, ren1->pair->two->sha1)) {
+ oid_eq(&dst_other.oid, &ren1->pair->two->oid)) {
/*
* Added file on the other side identical to
* the file being renamed: clean merge.
* update_file().
*/
update_file_flags(o,
- ren1->pair->two->sha1,
+ &ren1->pair->two->oid,
ren1->pair->two->mode,
ren1_dst,
1, /* update_cache */
0 /* update_wd */);
- } else if (!sha_eq(dst_other.sha1, null_sha1)) {
+ } else if (!oid_eq(&dst_other.oid, &null_oid)) {
clean_merge = 0;
try_merge = 1;
output(o, 1, _("CONFLICT (rename/add): Rename %s->%s in %s. "
ren1_dst, branch2);
if (o->call_depth) {
struct merge_file_info mfi;
- mfi = merge_file_one(o, ren1_dst, null_sha1, 0,
- ren1->pair->two->sha1, ren1->pair->two->mode,
- dst_other.sha1, dst_other.mode,
+ mfi = merge_file_one(o, ren1_dst, &null_oid, 0,
+ &ren1->pair->two->oid,
+ ren1->pair->two->mode,
+ &dst_other.oid,
+ dst_other.mode,
branch1, branch2);
output(o, 1, _("Adding merged %s"), ren1_dst);
- update_file(o, 0, mfi.sha, mfi.mode, ren1_dst);
+ update_file(o, 0, &mfi.oid,
+ mfi.mode, ren1_dst);
try_merge = 0;
} else {
char *new_path = unique_path(o, ren1_dst, branch2);
output(o, 1, _("Adding as %s instead"), new_path);
- update_file(o, 0, dst_other.sha1, dst_other.mode, new_path);
+ update_file(o, 0, &dst_other.oid,
+ dst_other.mode, new_path);
free(new_path);
}
} else
return clean_merge;
}
-static unsigned char *stage_sha(const unsigned char *sha, unsigned mode)
+static struct object_id *stage_oid(const struct object_id *oid, unsigned mode)
{
- return (is_null_sha1(sha) || mode == 0) ? NULL: (unsigned char *)sha;
+ return (is_null_oid(oid) || mode == 0) ? NULL: (struct object_id *)oid;
}
-static int read_sha1_strbuf(const unsigned char *sha1, struct strbuf *dst)
+static int read_oid_strbuf(const struct object_id *oid, struct strbuf *dst)
{
void *buf;
enum object_type type;
unsigned long size;
- buf = read_sha1_file(sha1, &type, &size);
+ buf = read_sha1_file(oid->hash, &type, &size);
if (!buf)
- return error(_("cannot read object %s"), sha1_to_hex(sha1));
+ return error(_("cannot read object %s"), oid_to_hex(oid));
if (type != OBJ_BLOB) {
free(buf);
- return error(_("object %s is not a blob"), sha1_to_hex(sha1));
+ return error(_("object %s is not a blob"), oid_to_hex(oid));
}
strbuf_attach(dst, buf, size, size + 1);
return 0;
}
-static int blob_unchanged(const unsigned char *o_sha,
+static int blob_unchanged(const struct object_id *o_oid,
unsigned o_mode,
- const unsigned char *a_sha,
+ const struct object_id *a_oid,
unsigned a_mode,
int renormalize, const char *path)
{
if (a_mode != o_mode)
return 0;
- if (sha_eq(o_sha, a_sha))
+ if (oid_eq(o_oid, a_oid))
return 1;
if (!renormalize)
return 0;
- assert(o_sha && a_sha);
- if (read_sha1_strbuf(o_sha, &o) || read_sha1_strbuf(a_sha, &a))
+ assert(o_oid && a_oid);
+ if (read_oid_strbuf(o_oid, &o) || read_oid_strbuf(a_oid, &a))
goto error_return;
/*
* Note: binary | is used so that both renormalizations are
static void handle_modify_delete(struct merge_options *o,
const char *path,
- unsigned char *o_sha, int o_mode,
- unsigned char *a_sha, int a_mode,
- unsigned char *b_sha, int b_mode)
+ struct object_id *o_oid, int o_mode,
+ struct object_id *a_oid, int a_mode,
+ struct object_id *b_oid, int b_mode)
{
handle_change_delete(o,
path,
- o_sha, o_mode,
- a_sha, a_mode,
- b_sha, b_mode,
+ o_oid, o_mode,
+ a_oid, a_mode,
+ b_oid, b_mode,
_("modify"), _("modified"));
}
static int merge_content(struct merge_options *o,
const char *path,
- unsigned char *o_sha, int o_mode,
- unsigned char *a_sha, int a_mode,
- unsigned char *b_sha, int b_mode,
+ struct object_id *o_oid, int o_mode,
+ struct object_id *a_oid, int a_mode,
+ struct object_id *b_oid, int b_mode,
struct rename_conflict_info *rename_conflict_info)
{
const char *reason = _("content");
struct diff_filespec one, a, b;
unsigned df_conflict_remains = 0;
- if (!o_sha) {
+ if (!o_oid) {
reason = _("add/add");
- o_sha = (unsigned char *)null_sha1;
+ o_oid = (struct object_id *)&null_oid;
}
one.path = a.path = b.path = (char *)path;
- hashcpy(one.sha1, o_sha);
+ oidcpy(&one.oid, o_oid);
one.mode = o_mode;
- hashcpy(a.sha1, a_sha);
+ oidcpy(&a.oid, a_oid);
a.mode = a_mode;
- hashcpy(b.sha1, b_sha);
+ oidcpy(&b.oid, b_oid);
b.mode = b_mode;
if (rename_conflict_info) {
o->branch2, path2);
if (mfi.clean && !df_conflict_remains &&
- sha_eq(mfi.sha, a_sha) && mfi.mode == a_mode) {
+ oid_eq(&mfi.oid, a_oid) && mfi.mode == a_mode) {
int path_renamed_outside_HEAD;
output(o, 3, _("Skipped %s (merged same as existing)"), path);
/*
*/
path_renamed_outside_HEAD = !path2 || !strcmp(path, path2);
if (!path_renamed_outside_HEAD) {
- add_cacheinfo(mfi.mode, mfi.sha, path,
+ add_cacheinfo(mfi.mode, &mfi.oid, path,
0, (!o->call_depth), 0);
return mfi.clean;
}
else {
int file_from_stage2 = was_tracked(path);
struct diff_filespec merged;
- hashcpy(merged.sha1, mfi.sha);
+ oidcpy(&merged.oid, &mfi.oid);
merged.mode = mfi.mode;
update_stages(path, NULL,
}
new_path = unique_path(o, path, rename_conflict_info->branch1);
output(o, 1, _("Adding as %s instead"), new_path);
- update_file(o, 0, mfi.sha, mfi.mode, new_path);
+ update_file(o, 0, &mfi.oid, mfi.mode, new_path);
free(new_path);
mfi.clean = 0;
} else {
- update_file(o, mfi.clean, mfi.sha, mfi.mode, path);
+ update_file(o, mfi.clean, &mfi.oid, mfi.mode, path);
}
return mfi.clean;
unsigned o_mode = entry->stages[1].mode;
unsigned a_mode = entry->stages[2].mode;
unsigned b_mode = entry->stages[3].mode;
- unsigned char *o_sha = stage_sha(entry->stages[1].sha, o_mode);
- unsigned char *a_sha = stage_sha(entry->stages[2].sha, a_mode);
- unsigned char *b_sha = stage_sha(entry->stages[3].sha, b_mode);
+ struct object_id *o_oid = stage_oid(&entry->stages[1].oid, o_mode);
+ struct object_id *a_oid = stage_oid(&entry->stages[2].oid, a_mode);
+ struct object_id *b_oid = stage_oid(&entry->stages[3].oid, b_mode);
entry->processed = 1;
if (entry->rename_conflict_info) {
case RENAME_NORMAL:
case RENAME_ONE_FILE_TO_ONE:
clean_merge = merge_content(o, path,
- o_sha, o_mode, a_sha, a_mode, b_sha, b_mode,
+ o_oid, o_mode, a_oid, a_mode, b_oid, b_mode,
conflict_info);
break;
case RENAME_DELETE:
entry->processed = 0;
break;
}
- } else if (o_sha && (!a_sha || !b_sha)) {
+ } else if (o_oid && (!a_oid || !b_oid)) {
/* Case A: Deleted in one */
- if ((!a_sha && !b_sha) ||
- (!b_sha && blob_unchanged(o_sha, o_mode, a_sha, a_mode, normalize, path)) ||
- (!a_sha && blob_unchanged(o_sha, o_mode, b_sha, b_mode, normalize, path))) {
+ if ((!a_oid && !b_oid) ||
+ (!b_oid && blob_unchanged(o_oid, o_mode, a_oid, a_mode, normalize, path)) ||
+ (!a_oid && blob_unchanged(o_oid, o_mode, b_oid, b_mode, normalize, path))) {
/* Deleted in both or deleted in one and
* unchanged in the other */
- if (a_sha)
+ if (a_oid)
output(o, 2, _("Removing %s"), path);
/* do not touch working file if it did not exist */
- remove_file(o, 1, path, !a_sha);
+ remove_file(o, 1, path, !a_oid);
} else {
/* Modify/delete; deleted side may have put a directory in the way */
clean_merge = 0;
- handle_modify_delete(o, path, o_sha, o_mode,
- a_sha, a_mode, b_sha, b_mode);
+ handle_modify_delete(o, path, o_oid, o_mode,
+ a_oid, a_mode, b_oid, b_mode);
}
- } else if ((!o_sha && a_sha && !b_sha) ||
- (!o_sha && !a_sha && b_sha)) {
+ } else if ((!o_oid && a_oid && !b_oid) ||
+ (!o_oid && !a_oid && b_oid)) {
/* Case B: Added in one. */
/* [nothing|directory] -> ([nothing|directory], file) */
const char *add_branch;
const char *other_branch;
unsigned mode;
- const unsigned char *sha;
+ const struct object_id *oid;
const char *conf;
- if (a_sha) {
+ if (a_oid) {
add_branch = o->branch1;
other_branch = o->branch2;
mode = a_mode;
- sha = a_sha;
+ oid = a_oid;
conf = _("file/directory");
} else {
add_branch = o->branch2;
other_branch = o->branch1;
mode = b_mode;
- sha = b_sha;
+ oid = b_oid;
conf = _("directory/file");
}
if (dir_in_way(path, !o->call_depth)) {
output(o, 1, _("CONFLICT (%s): There is a directory with name %s in %s. "
"Adding %s as %s"),
conf, path, other_branch, path, new_path);
- if (o->call_depth)
- remove_file_from_cache(path);
- update_file(o, 0, sha, mode, new_path);
+ update_file(o, 0, oid, mode, new_path);
if (o->call_depth)
remove_file_from_cache(path);
free(new_path);
} else {
output(o, 2, _("Adding %s"), path);
/* do not overwrite file if already present */
- update_file_flags(o, sha, mode, path, 1, !a_sha);
+ update_file_flags(o, oid, mode, path, 1, !a_oid);
}
- } else if (a_sha && b_sha) {
+ } else if (a_oid && b_oid) {
/* Case C: Added in both (check for same permissions) and */
/* case D: Modified in both, but differently. */
clean_merge = merge_content(o, path,
- o_sha, o_mode, a_sha, a_mode, b_sha, b_mode,
+ o_oid, o_mode, a_oid, a_mode, b_oid, b_mode,
NULL);
- } else if (!o_sha && !a_sha && !b_sha) {
+ } else if (!o_oid && !a_oid && !b_oid) {
/*
* this entry was deleted altogether. a_mode == 0 means
* we had that path and want to actively remove it.
common = shift_tree_object(head, common, o->subtree_shift);
}
- if (sha_eq(common->object.oid.hash, merge->object.oid.hash)) {
+ if (oid_eq(&common->object.oid, &merge->object.oid)) {
output(o, 0, _("Already up-to-date!"));
*result = head;
return 1;
return clean;
}
-static struct commit *get_ref(const unsigned char *sha1, const char *name)
+static struct commit *get_ref(const struct object_id *oid, const char *name)
{
struct object *object;
- object = deref_tag(parse_object(sha1), name, strlen(name));
+ object = deref_tag(parse_object(oid->hash), name, strlen(name));
if (!object)
return NULL;
if (object->type == OBJ_TREE)
}
int merge_recursive_generic(struct merge_options *o,
- const unsigned char *head,
- const unsigned char *merge,
+ const struct object_id *head,
+ const struct object_id *merge,
int num_base_list,
- const unsigned char **base_list,
+ const struct object_id **base_list,
struct commit **result)
{
int clean;
int i;
for (i = 0; i < num_base_list; ++i) {
struct commit *base;
- if (!(base = get_ref(base_list[i], sha1_to_hex(base_list[i]))))
+ if (!(base = get_ref(base_list[i], oid_to_hex(base_list[i]))))
return error(_("Could not parse object '%s'"),
- sha1_to_hex(base_list[i]));
+ oid_to_hex(base_list[i]));
commit_list_insert(base, &ca);
}
}
#include "split-index.h"
#include "utf8.h"
- static struct cache_entry *refresh_cache_entry(struct cache_entry *ce,
- unsigned int options);
-
/* Mask for the name length in ce_flags in the on-disk index */
#define CE_NAMEMASK (0x0fff)
hashcpy(ce->sha1, sha1);
}
-int add_to_index(struct index_state *istate, const char *path, struct stat *st, int flags)
+int add_to_index(struct index_state *istate, const char *path, struct stat *st, int flags, int force_mode)
{
int size, namelen, was_same;
mode_t st_mode = st->st_mode;
else
ce->ce_flags |= CE_INTENT_TO_ADD;
- if (trust_executable_bit && has_symlinks)
+ if (S_ISREG(st_mode) && force_mode)
+ ce->ce_mode = create_ce_mode(force_mode);
+ else if (trust_executable_bit && has_symlinks)
ce->ce_mode = create_ce_mode(st_mode);
else {
/* If there is an existing entry, pick the mode bits and type
return 0;
}
-int add_file_to_index(struct index_state *istate, const char *path, int flags)
+int add_file_to_index(struct index_state *istate, const char *path,
+ int flags, int force_mode)
{
struct stat st;
if (lstat(path, &st))
die_errno("unable to stat '%s'", path);
- return add_to_index(istate, path, &st, flags);
+ return add_to_index(istate, path, &st, flags, force_mode);
}
struct cache_entry *make_cache_entry(unsigned int mode,
return has_errors;
}
- static struct cache_entry *refresh_cache_entry(struct cache_entry *ce,
+ struct cache_entry *refresh_cache_entry(struct cache_entry *ce,
unsigned int options)
{
return refresh_cache_ent(&the_index, ce, options, NULL, NULL);