Commit Graph

9168 Commits

Author SHA1 Message Date
Paolo Bonzini
8d81408435 git-send-email: add --transfer-encoding option
The thread at http://thread.gmane.org/gmane.comp.version-control.git/257392
details problems when applying patches with "git am" in a repository with
CRLF line endings.  In the example in the thread, the repository originated
from "git-svn" so it is not possible to use core.eol and friends on it.

Right now, the best option is to use "git am --keep-cr".  However, when
a patch create new files, the patch application process will reject the
new file because it finds a "/dev/null\r" string instead of "/dev/null".

The problem is that SMTP transport is CRLF-unsafe.  Sending a patch by
email is the same as passing it through "dos2unix | unix2dos".  The newly
introduced CRLFs are normally transparent because git-am strips them. The
keepcr=true setting preserves them, but it is mostly working by chance
and it would be very problematic to have a "git am" workflow in a
repository with mixed LF and CRLF line endings.

The MIME solution to this is the quoted-printable transfer enconding.
This is not something that we want to enable by default, since it makes
received emails horrible to look at.  However, it is a very good match
for projects that store CRLF line endings in the repository.

The only disadvantage of quoted-printable is that quoted-printable
patches fail to apply if the maintainer uses "git am --keep-cr".  This
is because the decoded patch will have two carriage returns at the end
of the line.  Therefore, add support for base64 transfer encoding too,
which makes received emails downright impossible to look at outside
a MUA, but really just works.

The patch covers all bases, including users that still live in the late
80s, by also providing a 7bit content transfer encoding that refuses
to send emails with non-ASCII character in them.  And finally, "8bit"
will add a Content-Transfer-Encoding header but otherwise do nothing.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-11-25 14:00:15 -08:00
Junio C Hamano
f00e081a9a Merge branch 'tb/no-relative-file-url'
* tb/no-relative-file-url:
  t5705: the file:// URL should be absolute
2014-11-19 13:47:53 -08:00
Junio C Hamano
3f78278beb Merge branch 'da/difftool'
Fix-up to a new feature in 'master'.

* da/difftool:
  difftool: honor --trust-exit-code for builtin tools
2014-11-18 10:16:55 -08:00
David Aguilar
99474b6340 difftool: honor --trust-exit-code for builtin tools
run_merge_tool() was not setting $status, which prevented the
exit code for builtin tools from being forwarded to the caller.

Capture the exit status and add a test to guarantee the behavior.

Reported-by: Adria Farres <14farresa@gmail.com>
Signed-off-by: David Aguilar <davvid@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-11-14 13:40:38 -08:00
Torsten Bögershausen
f904f6603a t5705: the file:// URL should be absolute
The test misused a URL "file://." to mean "relative to here",
which we no longer accept.

In a file:// URL, typically there is no host, and RFC1738 says that
file:///<path> should be used.

Update t5705 to use a working URL.

Reported-by: Michael Blume <blume.mike@gmail.com>
Signed-off-by: Torsten Bögershausen <tboegi@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-11-13 10:41:56 -08:00
Junio C Hamano
bbebdc1dca Merge branch 'jk/fetch-reflog-df-conflict'
Fix-up a test for portability.

* jk/fetch-reflog-df-conflict:
  t1410: fix breakage on case-insensitive filesystems
2014-11-12 11:59:58 -08:00
Jeff King
aae828b911 t1410: fix breakage on case-insensitive filesystems
Two tests recently added to t1410 create branches "a" and
"a/b" to test d/f conflicts on reflogs. Earlier, unrelated
tests in that script create the path "A/B" in the working
tree.  There's no conflict on a case-sensitive filesystem,
but on a case-insensitive one, "git log" will complain that
"a/b" is both a revision and a working tree path.

We could fix this by using a "--" to disambiguate, but we
are probably better off using names that are less confusing
to make it more clear that they are unrelated to the working
tree files.  This patch turns "a/b" into "one/two".

Reported-by: Michael Blume <blume.mike@gmail.com>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-11-10 09:38:53 -08:00
Junio C Hamano
64b9326460 Merge branch 'tm/line-log-first-parent'
"git log --first-parent -L..." used to crash.

* tm/line-log-first-parent:
  line-log: fix crash when --first-parent is used
2014-11-06 10:52:37 -08:00
Junio C Hamano
a1671dd82b Merge branch 'jk/fetch-reflog-df-conflict'
Corner-case bugfixes for "git fetch" around reflog handling.

* jk/fetch-reflog-df-conflict:
  ignore stale directories when checking reflog existence
  fetch: load all default config at startup
2014-11-06 10:52:32 -08:00
Tzvetan Mikov
a8787c5c1c line-log: fix crash when --first-parent is used
line-log tries to access all parents of a commit, but only the first
parent has been loaded if "--first-parent" is specified, resulting
in a crash.

Limit the number of parents to one if "--first-parent" is specified.

Reported-by: Eric N. Vander Weele <ericvw@gmail.com>
Signed-off-by: Tzvetan Mikov <tmikov@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-11-04 12:47:35 -08:00
Jeff King
9233887cce ignore stale directories when checking reflog existence
When we update a ref, we have two rules for whether or not
we actually update the reflog:

  1. If the reflog already exists, we will always append to
     it.

  2. If log_all_ref_updates is set, we will create a new
     reflog file if necessary.

We do the existence check by trying to open the reflog file,
either with or without O_CREAT (depending on log_all_ref_updates).
If it fails, then we check errno to see what happened.

If we were not using O_CREAT and we got ENOENT, the file
doesn't exist, and we return success (there isn't a reflog
already, and we were not told to make a new one).

If we get EISDIR, then there is likely a stale directory
that needs to be removed (e.g., there used to be "foo/bar",
it was deleted, and the directory "foo" was left. Now we
want to create the ref "foo"). If O_CREAT is set, then we
catch this case, try to remove the directory, and retry our
open. So far so good.

But if we get EISDIR and O_CREAT is not set, then we treat
this as any other error, which is not right. Like ENOENT,
EISDIR is an indication that we do not have a reflog, and we
should silently return success (we were not told to create
it). Instead, the current code reports this as an error, and
we fail to update the ref at all.

Note that this is relatively unlikely to happen, as you
would have to have had reflogs turned on, and then later
turned them off (it could also happen due to a bug in fetch,
but that was fixed in the previous commit). However, it's
quite easy to fix: we just need to treat EISDIR like ENOENT
for the non-O_CREAT case, and silently return (note that
this early return means we can also simplify the O_CREAT
case).

Our new tests cover both cases (O_CREAT and non-O_CREAT).
The first one already worked, of course.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-11-04 12:18:44 -08:00
Jeff King
72549dfd5d fetch: load all default config at startup
When we start the git-fetch program, we call git_config to
load all config, but our callback only processes the
fetch.prune option; we do not chain to git_default_config at
all.

This means that we may not load some core configuration
which will have an effect. For instance, we do not load
core.logAllRefUpdates, which impacts whether or not we
create reflogs in a bare repository.

Note that I said "may" above. It gets even more exciting. If
we have to transfer actual objects as part of the fetch,
then we call fetch_pack as part of the same process. That
function loads its own config, which does chain to
git_default_config, impacting global variables which are
used by the rest of fetch. But if the fetch is a pure ref
update (e.g., a new ref which is a copy of an old one), we
skip fetch_pack entirely. So we get inconsistent results
depending on whether or not we have actual objects to
transfer or not!

Let's just load the core config at the start of fetch, so we
know we have it (we may also load it again as part of
fetch_pack, but that's OK; it's designed to be idempotent).

Our tests check both cases (with and without a pack). We
also check similar behavior for push for good measure, but
it already works as expected.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-11-04 12:13:46 -08:00
Junio C Hamano
bf1f639ea2 Merge branch 'rs/grep-color-words'
Allow painting or not painting (partial) matches in context lines
when showing "grep -C<num>" output in color.

* rs/grep-color-words:
  grep: add color.grep.matchcontext and color.grep.matchselected
2014-10-31 11:49:47 -07:00
Junio C Hamano
ebc2e5a593 Merge branch 'jk/pack-objects-no-bitmap-when-splitting' into maint
* jk/pack-objects-no-bitmap-when-splitting:
  pack-objects: turn off bitmaps when we split packs
2014-10-29 10:35:17 -07:00
Junio C Hamano
9ce57f1228 Merge branch 'da/difftool'
Allow diff tool backend to stop early by exiting with a non-zero
status.

* da/difftool:
  difftool: add support for --trust-exit-code
  difftool--helper: exit when reading a prompt answer fails
2014-10-29 10:09:35 -07:00
Junio C Hamano
7654ca6963 Merge branch 'mg/lib-gpg-ro-safety'
In a tarball extract whose files are all read-only, running GPG
tests would have failed due to unwritable files.

* mg/lib-gpg-ro-safety:
  t/lib-gpg: make gpghome files writable
2014-10-29 10:08:16 -07:00
Junio C Hamano
d70e331c0e Merge branch 'jk/prune-mtime'
Tighten the logic to decide that an unreachable cruft is
sufficiently old by covering corner cases such as an ancient object
becoming reachable and then going unreachable again, in which case
its retention period should be prolonged.

* jk/prune-mtime: (28 commits)
  drop add_object_array_with_mode
  revision: remove definition of unused 'add_object' function
  pack-objects: double-check options before discarding objects
  repack: pack objects mentioned by the index
  pack-objects: use argv_array
  reachable: use revision machinery's --indexed-objects code
  rev-list: add --indexed-objects option
  rev-list: document --reflog option
  t5516: test pushing a tag of an otherwise unreferenced blob
  traverse_commit_list: support pending blobs/trees with paths
  make add_object_array_with_context interface more sane
  write_sha1_file: freshen existing objects
  pack-objects: match prune logic for discarding objects
  pack-objects: refactor unpack-unreachable expiration check
  prune: keep objects reachable from recent objects
  sha1_file: add for_each iterators for loose and packed objects
  count-objects: use for_each_loose_file_in_objdir
  count-objects: do not use xsize_t when counting object size
  prune-packed: use for_each_loose_file_in_objdir
  reachable: mark index blobs as SEEN
  ...
2014-10-29 10:07:56 -07:00
David Aguilar
2b52123fcf difftool: add support for --trust-exit-code
Teach difftool to exit when a diff tool returns a non-zero exit
code when either --trust-exit-code is specified or
difftool.trustExitCode is true.

Forward exit codes from invoked diff tools to the caller when
--trust-exit-code is used.

Suggested-by: Adri Farr <14farresa@gmail.com>
Helped-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: David Aguilar <davvid@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-10-28 10:36:57 -07:00
René Scharfe
79a77109d3 grep: add color.grep.matchcontext and color.grep.matchselected
The config option color.grep.match can be used to specify the highlighting
color for matching strings.  Add the options matchContext and matchSelected
to allow different colors to be specified for matching strings in the
context vs. in selected lines.  This is similar to the ms and mc specifiers
in GNU grep's environment variable GREP_COLORS.

Tests are from Zoltan Klinger's earlier attempt to solve the same
issue in a different way.

Signed-off-by: Rene Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-10-28 10:33:50 -07:00
Michael J Gruber
e7f224f780 t/lib-gpg: make gpghome files writable
t/lib-gpg.sh copies the test environment's gpg home to the trash
directory and makes sure the directoty is writable.

Make sure the copied files are writable, too.

Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-10-27 12:09:36 -07:00
Johannes Sixt
25098690a0 difftool--helper: exit when reading a prompt answer fails
An attempt to quit difftool by hitting Ctrl-D (EOF) at its prompt does
not quit it, but is treated as if 'yes' was answered to the prompt and
all following prompts, which is contrary to the user's intent. Fix the
error check.

Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-10-27 11:17:56 -07:00
Junio C Hamano
a33043f639 Merge branch 'jc/push-cert'
* jc/push-cert:
  push: heed user.signingkey for signed pushes
2014-10-24 15:01:32 -07:00
Junio C Hamano
bb8caad381 Merge branch 'wk/t1304-wo-USER'
* wk/t1304-wo-USER:
  t1304: Set LOGNAME even if USER is unset or null
2014-10-24 14:59:02 -07:00
Junio C Hamano
26a22d8d00 Merge branch 'jk/pack-objects-no-bitmap-when-splitting'
Splitting pack-objects output into multiple packs is incompatible
with the use of reachability bitmap.

* jk/pack-objects-no-bitmap-when-splitting:
  pack-objects: turn off bitmaps when we split packs
2014-10-24 14:56:10 -07:00
Michael J Gruber
b9459019bb push: heed user.signingkey for signed pushes
push --signed promises to take user.signingkey as the signing key but
fails to read the config.

Make it do so.

Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-10-24 10:50:05 -07:00
Junio C Hamano
a46af5946c Merge branch 'da/mergetool-temporary-directory'
Allow a temporary directory specified to be used while running "git
mergetool" backend.

* da/mergetool-temporary-directory:
  t7610-mergetool: add test cases for mergetool.writeToTemp
  mergetool: add an option for writing to a temporary directory
2014-10-21 13:28:42 -07:00
Junio C Hamano
e96e98b339 Merge branch 'da/mergetool-tool-help'
Allow "git mergetool --help" to run outside a Git repository.

* da/mergetool-tool-help:
  difftool: don't assume that default sh is sane
  mergetool: don't require a work tree for --tool-help
  git-sh-setup: move GIT_DIR initialization into a function
  mergetool: use more conservative temporary filenames
  test-lib-functions: adjust style to match CodingGuidelines
  t7610-mergetool: prefer test_config over git config
2014-10-21 13:28:37 -07:00
Junio C Hamano
64bff25f78 Merge branch 'da/mergetool-tests'
The clean-up of this test script was long overdue and is a very
welcome change.

* da/mergetool-tests:
  test-lib-functions: adjust style to match CodingGuidelines
  t7610-mergetool: use test_config to isolate tests
  t7610-mergetool: add missing && and remove commented-out code
  t7610-mergetool: use tabs instead of a mix of tabs and spaces
2014-10-21 13:28:14 -07:00
Junio C Hamano
3c85452bb0 Merge branch 'rs/ref-transaction'
The API to update refs have been restructured to allow introducing
a true transactional updates later.  We would even allow storing
refs in backends other than the traditional filesystem-based one.

* rs/ref-transaction: (25 commits)
  ref_transaction_commit: bail out on failure to remove a ref
  lockfile: remove unable_to_lock_error
  refs.c: do not permit err == NULL
  remote rm/prune: print a message when writing packed-refs fails
  for-each-ref: skip and warn about broken ref names
  refs.c: allow listing and deleting badly named refs
  test: put tests for handling of bad ref names in one place
  packed-ref cache: forbid dot-components in refnames
  branch -d: simplify by using RESOLVE_REF_READING
  branch -d: avoid repeated symref resolution
  reflog test: test interaction with detached HEAD
  refs.c: change resolve_ref_unsafe reading argument to be a flags field
  refs.c: make write_ref_sha1 static
  fetch.c: change s_update_ref to use a ref transaction
  refs.c: ref_transaction_commit: distinguish name conflicts from other errors
  refs.c: pass a list of names to skip to is_refname_available
  refs.c: call lock_ref_sha1_basic directly from commit
  refs.c: refuse to lock badly named refs in lock_ref_sha1_basic
  rename_ref: don't ask read_ref_full where the ref came from
  refs.c: pass the ref log message to _create/delete/update instead of _commit
  ...
2014-10-21 13:28:10 -07:00
Junio C Hamano
9d04401ffe Merge branch 'cc/interpret-trailers'
A new filter to programatically edit the tail end of the commit log
messages.

* cc/interpret-trailers:
  Documentation: add documentation for 'git interpret-trailers'
  trailer: add tests for commands in config file
  trailer: execute command from 'trailer.<name>.command'
  trailer: add tests for "git interpret-trailers"
  trailer: add interpret-trailers command
  trailer: put all the processing together and print
  trailer: parse trailers from file or stdin
  trailer: process command line trailer arguments
  trailer: read and process config information
  trailer: process trailers from input message and arguments
  trailer: add data structures and basic functions
2014-10-20 12:25:32 -07:00
Junio C Hamano
713ee7fe46 Merge branch 'ta/config-set'
* ta/config-set:
  t1308: fix broken here document in test script
2014-10-20 12:23:43 -07:00
Junio C Hamano
f9a2fd3616 Merge branch 'jk/test-shell-trace'
Test scripts were taught to notice "-x" option to show shell trace,
as if the tests were run under "sh -x".

* jk/test-shell-trace:
  test-lib.sh: support -x option for shell-tracing
  t5304: use helper to report failure of "test foo = bar"
  t5304: use test_path_is_* instead of "test -f"
2014-10-20 12:23:40 -07:00
Junio C Hamano
15c6ef7b06 Revert "archive: honor tar.umask even for pax headers"
This reverts commit 10f343ea81, whose
output is no longer bit-for-bit equivalent from the older versions
of Git, which the infrastructure to (pretend to) upload tarballs
kernel.org uses depends on.
2014-10-20 12:04:46 -07:00
W. Trevor King
7544b2e2da t1304: Set LOGNAME even if USER is unset or null
Avoid:

  # ./t1304-default-acl.sh
  ok 1 - checking for a working acl setup
  ok 2 - Setup test repo
  not ok 3 - Objects creation does not break ACLs with restrictive umask
  #
  #               # SHA1 for empty blob
  #               check_perms_and_acl .git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
  #
  not ok 4 - git gc does not break ACLs with restrictive umask
  #
  #               git gc &&
  #               check_perms_and_acl .git/objects/pack/*.pack
  #
  # failed 2 among 4 test(s)
  1..4

on systems where USER isn't set.  It's usually set by the login
process, but it isn't set when launching some Docker images.  For
example:

  $ docker run --rm debian env
  HOME=/
  PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
  HOSTNAME=b2dfdfe797ed

'id -u -n' has been in POSIX from Issue 2 through 2013 [1], so I don't
expect compatibility issues.

[1]: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/id.html

Signed-off-by: W. Trevor King <wking@tremily.us>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-10-19 15:47:20 -07:00
Jeff King
2113471478 pack-objects: turn off bitmaps when we split packs
If a pack.packSizeLimit is set, we may split the pack data
across multiple packfiles. This means we cannot generate
.bitmap files, as they require that all of the reachable
objects are in the same pack. We check that condition when
we are generating the list of objects to pack (and disable
bitmaps if we are not packing everything), but we forgot to
update it when we notice that we needed to split (which
doesn't happen until the actual write phase).

The resulting bitmaps are quite bogus (they mention entries
that do not exist in the pack!) and can cause a fetch or
push to send insufficient objects.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-10-19 15:08:38 -07:00
Jeff King
c90f9e13ab repack: pack objects mentioned by the index
When we pack all objects, we use only the objects reachable
from references and reflogs. This misses any objects which
are reachable from the index, but not yet referenced.

By itself this isn't a big deal; the objects can remain
loose until they are actually used in a commit. However, it
does create a problem when we drop packed but unreachable
objects. We try to optimize out the writing of objects that
we will immediately prune, which means we must follow the
same rules as prune in determining what is reachable. And
prune uses the index for this purpose.

This is rather uncommon in practice, as objects in the index
would not usually have been packed in the first place. But
it could happen in a sequence like:

  1. You make a commit on a branch that references blob X.

  2. You repack, moving X into the pack.

  3. You delete the branch (and its reflog), so that X is
     unreferenced.

  4. You "git add" blob X so that it is now referenced only
     by the index.

  5. You repack again with git-gc. The pack-objects we
     invoke will see that X is neither referenced nor
     recent and not bother loosening it.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-10-19 15:07:07 -07:00
Jeff King
4fe10219bc rev-list: add --indexed-objects option
There is currently no easy way to ask the revision traversal
machinery to include objects reachable from the index (e.g.,
blobs and trees that have not yet been committed). This
patch adds an option to do so.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-10-19 15:07:07 -07:00
Jeff King
458a7e508c t5516: test pushing a tag of an otherwise unreferenced blob
It's not unreasonable to have a tag that points to a blob
that is not part of the normal history. We do this in
git.git to distribute gpg keys. However, we never explicitly
checked in our test suite that this actually works (i.e.,
that pack-objects actually sends the blob because of the tag
mentioning it).

It does in fact work fine, but a recent patch under
discussion broke this, and the test suite didn't notice.
Let's make the test suite more complete.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-10-19 15:07:06 -07:00
David Aguilar
688684eba4 t7610-mergetool: add test cases for mergetool.writeToTemp
Add tests to ensure that filenames start with "./" when
mergetool.writeToTemp is false and do not start with "./" when
mergetool.writeToTemp is true.

Signed-off-by: David Aguilar <davvid@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-10-16 12:09:51 -07:00
David Aguilar
9e8f8dea46 test-lib-functions: adjust style to match CodingGuidelines
Prefer "test" over "[ ]" for conditionals.
Prefer "$()" over backticks for command substitutions.
Avoid control structures on a single line with semicolons.

Signed-off-by: David Aguilar <davvid@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-10-16 12:04:05 -07:00
David Aguilar
d7d300ea59 t7610-mergetool: use test_config to isolate tests
Signed-off-by: David Aguilar <davvid@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-10-16 12:03:21 -07:00
Jeff King
33d4221c79 write_sha1_file: freshen existing objects
When we try to write a loose object file, we first check
whether that object already exists. If so, we skip the
write as an optimization. However, this can interfere with
prune's strategy of using mtimes to mark files in progress.

For example, if a branch contains a particular tree object
and is deleted, that tree object may become unreachable, and
have an old mtime. If a new operation then tries to write
the same tree, this ends up as a noop; we notice we
already have the object and do nothing. A prune running
simultaneously with this operation will see the object as
old, and may delete it.

We can solve this by "freshening" objects that we avoid
writing by updating their mtime. The algorithm for doing so
is essentially the same as that of has_sha1_file. Therefore
we provide a new (static) interface "check_and_freshen",
which finds and optionally freshens the object. It's trivial
to implement freshening and simple checking by tweaking a
single parameter.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-10-16 10:10:43 -07:00
Jeff King
abcb86553d pack-objects: match prune logic for discarding objects
A recent commit taught git-prune to keep non-recent objects
that are reachable from recent ones. However, pack-objects,
when loosening unreachable objects, tries to optimize out
the write in the case that the object will be immediately
pruned. It now gets this wrong, since its rule does not
reflect the new prune code (and this can be seen by running
t6501 with a strategically placed repack).

Let's teach pack-objects similar logic.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-10-16 10:10:43 -07:00
Jeff King
d3038d22f9 prune: keep objects reachable from recent objects
Our current strategy with prune is that an object falls into
one of three categories:

  1. Reachable (from ref tips, reflogs, index, etc).

  2. Not reachable, but recent (based on the --expire time).

  3. Not reachable and not recent.

We keep objects from (1) and (2), but prune objects in (3).
The point of (2) is that these objects may be part of an
in-progress operation that has not yet updated any refs.

However, it is not always the case that objects for an
in-progress operation will have a recent mtime. For example,
the object database may have an old copy of a blob (from an
abandoned operation, a branch that was deleted, etc). If we
create a new tree that points to it, a simultaneous prune
will leave our tree, but delete the blob. Referencing that
tree with a commit will then work (we check that the tree is
in the object database, but not that all of its referred
objects are), as will mentioning the commit in a ref. But
the resulting repo is corrupt; we are missing the blob
reachable from a ref.

One way to solve this is to be more thorough when
referencing a sha1: make sure that not only do we have that
sha1, but that we have objects it refers to, and so forth
recursively. The problem is that this is very expensive.
Creating a parent link would require traversing the entire
object graph!

Instead, this patch pushes the extra work onto prune, which
runs less frequently (and has to look at the whole object
graph anyway). It creates a new category of objects: objects
which are not recent, but which are reachable from a recent
object. We do not prune these objects, just like the
reachable and recent ones.

This lets us avoid the recursive check above, because if we
have an object, even if it is unreachable, we should have
its referent. We can make a simple inductive argument that
with this patch, this property holds (that there are no
objects with missing referents in the repository):

  0. When we have no objects, we have nothing to refer or be
     referred to, so the property holds.

  1. If we add objects to the repository, their direct
     referents must generally exist (e.g., if you create a
     tree, the blobs it references must exist; if you create
     a commit to point at the tree, the tree must exist).
     This is already the case before this patch. And it is
     not 100% foolproof (you can make bogus objects using
     `git hash-object`, for example), but it should be the
     case for normal usage.

     Therefore for any sequence of object additions, the
     property will continue to hold.

  2. If we remove objects from the repository, then we will
     not remove a child object (like a blob) if an object
     that refers to it is being kept. That is the part
     implemented by this patch.

     Note, however, that our reachability check and the
     actual pruning are not atomic. So it _is_ still
     possible to violate the property (e.g., an object
     becomes referenced just as we are deleting it). This
     patch is shooting for eliminating problems where the
     mtimes of dependent objects differ by hours or days,
     and one is dropped without the other. It does nothing
     to help with short races.

Naively, the simplest way to implement this would be to add
all recent objects as tips to the reachability traversal.
However, this does not perform well. In a recently-packed
repository, all reachable objects will also be recent, and
therefore we have to look at each object twice. This patch
instead performs the reachability traversal, then follows up
with a second traversal for recent objects, skipping any
that have already been marked.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-10-16 10:10:42 -07:00
David Aguilar
76ee96a9b6 test-lib-functions: adjust style to match CodingGuidelines
Prefer "test" over "[ ]" for conditionals.
Prefer "$()" over backticks for command substitutions.
Avoid control structures on a single line with semicolons.

Signed-off-by: David Aguilar <davvid@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-10-15 14:09:15 -07:00
David Aguilar
f9e43085bb t7610-mergetool: prefer test_config over git config
Signed-off-by: David Aguilar <davvid@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-10-15 13:49:11 -07:00
David Aguilar
4756c05741 t7610-mergetool: add missing && and remove commented-out code
Signed-off-by: David Aguilar <davvid@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-10-15 13:48:15 -07:00
David Aguilar
74578618a0 t7610-mergetool: use tabs instead of a mix of tabs and spaces
Signed-off-by: David Aguilar <davvid@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-10-15 13:47:51 -07:00
Ronnie Sahlberg
d0f810f0bc refs.c: allow listing and deleting badly named refs
We currently do not handle badly named refs well:

  $ cp .git/refs/heads/master .git/refs/heads/master.....@\*@\\.
  $ git branch
    fatal: Reference has invalid format: 'refs/heads/master.....@*@\.'
  $ git branch -D master.....@\*@\\.
    error: branch 'master.....@*@\.' not found.

Users cannot recover from a badly named ref without manually finding
and deleting the loose ref file or appropriate line in packed-refs.
Making that easier will make it easier to tweak the ref naming rules
in the future, for example to forbid shell metacharacters like '`'
and '"', without putting people in a state that is hard to get out of.

So allow "branch --list" to show these refs and allow "branch -d/-D"
and "update-ref -d" to delete them.  Other commands (for example to
rename refs) will continue to not handle these refs but can be changed
in later patches.

Details:

In resolving functions, refuse to resolve refs that don't pass the
git-check-ref-format(1) check unless the new RESOLVE_REF_ALLOW_BAD_NAME
flag is passed.  Even with RESOLVE_REF_ALLOW_BAD_NAME, refuse to
resolve refs that escape the refs/ directory and do not match the
pattern [A-Z_]* (think "HEAD" and "MERGE_HEAD").

In locking functions, refuse to act on badly named refs unless they
are being deleted and either are in the refs/ directory or match [A-Z_]*.

Just like other invalid refs, flag resolved, badly named refs with the
REF_ISBROKEN flag, treat them as resolving to null_sha1, and skip them
in all iteration functions except for for_each_rawref.

Flag badly named refs (but not symrefs pointing to badly named refs)
with a REF_BAD_NAME flag to make it easier for future callers to
notice and handle them specially.  For example, in a later patch
for-each-ref will use this flag to detect refs whose names can confuse
callers parsing for-each-ref output.

In the transaction API, refuse to create or update badly named refs,
but allow deleting them (unless they try to escape refs/ and don't match
[A-Z_]*).

Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-10-15 10:47:26 -07:00
Ronnie Sahlberg
8159f4af7d test: put tests for handling of bad ref names in one place
There's no straightforward way to grep for all tests dealing with
invalid refs.  Put them in a single test script so it is easy to see
what functionality has not been exercised with bad ref names yet.

Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-10-15 10:47:25 -07:00