Commit Graph

791 Commits

Author SHA1 Message Date
Junio C Hamano
2c2b6646c2 Revert "Add new @ shortcut for HEAD"
This reverts commit cdfd94837b, as it
does not just apply to "@" (and forms with modifiers like @{u}
applied to it), but also affects e.g. "refs/heads/@/foo", which it
shouldn't.

The basic idea of giving a short-hand might be good, and the topic
can be retried later, but let's revert to avoid affecting existing
use cases for now for the upcoming release.
2013-08-14 15:04:24 -07:00
Junio C Hamano
f1093b0f60 Merge branch 'mh/packed-refs-do-one-ref-recursion'
Fix a NULL-pointer dereference during nested iterations over
references (for example, when replace references are being used).

* mh/packed-refs-do-one-ref-recursion:
  do_one_ref(): save and restore value of current_ref
2013-07-31 12:38:12 -07:00
Junio C Hamano
29143fc4e3 Merge branch 'mh/ref-races-optim-invalidate-cached'
* mh/ref-races-optim-invalidate-cached:
  refs: do not invalidate the packed-refs cache unnecessarily
2013-07-24 19:21:02 -07:00
Michael Haggerty
d0cf51e940 do_one_ref(): save and restore value of current_ref
If do_one_ref() is called recursively, then the inner call should not
permanently overwrite the value stored in current_ref by the outer
call.  Aside from the tiny optimization loss, peel_ref() expects the
value of current_ref not to change across a call to peel_entry().  But
in the presence of replace references that assumption could be
violated by a recursive call to do_one_ref:

do_for_each_entry()
  do_one_ref()
    builtin/describe.c:get_name()
      peel_ref()
        peel_entry()
          peel_object ()
            deref_tag_noverify()
              parse_object()
                lookup_replace_object()
                  do_lookup_replace_object()
                    prepare_replace_object()
                      do_for_each_ref()
                        do_for_each_entry()
                          do_for_each_entry_in_dir()
                            do_one_ref()

The inner call to do_one_ref() was unconditionally setting current_ref
to NULL when it was done, causing peel_ref() to perform an invalid
memory access.

So change do_one_ref() to save the old value of current_ref before
overwriting it, and restore the old value afterward rather than
setting it to NULL.

Reported-by: Mantas Mikulėnas <grawity@gmail.com>
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-07-17 18:19:16 -07:00
Junio C Hamano
47a5918536 cache.h: move remote/connect API out of it
The definition of "struct ref" in "cache.h", a header file so
central to the system, always confused me.  This structure is not
about the local ref used by sha1-name API to name local objects.

It is what refspecs are expanded into, after finding out what refs
the other side has, to define what refs are updated after object
transfer succeeds to what values.  It belongs to "remote.h" together
with "struct refspec".

While we are at it, also move the types and functions related to the
Git transport connection to a new header file connect.h

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-07-08 14:34:24 -07:00
Junio C Hamano
079424a2cf Merge branch 'mh/ref-races'
"git pack-refs" that races with new ref creation or deletion have
been susceptible to lossage of refs under right conditions, which
has been tightened up.

* mh/ref-races:
  for_each_ref: load all loose refs before packed refs
  get_packed_ref_cache: reload packed-refs file when it changes
  add a stat_validity struct
  Extract a struct stat_data from cache_entry
  packed_ref_cache: increment refcount when locked
  do_for_each_entry(): increment the packed refs cache refcount
  refs: manage lifetime of packed refs cache via reference counting
  refs: implement simple transactions for the packed-refs file
  refs: wrap the packed refs cache in a level of indirection
  pack_refs(): split creation of packed refs and entry writing
  repack_without_ref(): split list curation and entry writing
2013-06-30 15:40:05 -07:00
Michael Haggerty
5d478f5ca1 refs: do not invalidate the packed-refs cache unnecessarily
Now that we keep track of the packed-refs file metadata, we can detect
when the packed-refs file has been modified since we last read it, and
we do so automatically every time that get_packed_ref_cache() is
called.  So there is no need to invalidate the cache automatically
when lock_packed_refs() is called; usually the old copy will still be
valid.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-06-20 15:50:17 -07:00
Jeff King
98eeb09e8a for_each_ref: load all loose refs before packed refs
If we are iterating through the refs using for_each_ref (or
any of its sister functions), we can get into a race
condition with a simultaneous "pack-refs --prune" that looks
like this:

  0. We have a large number of loose refs, and a few packed
     refs. refs/heads/z/foo is loose, with no matching entry
     in the packed-refs file.

  1. Process A starts iterating through the refs. It loads
     the packed-refs file from disk, then starts lazily
     traversing through the loose ref directories.

  2. Process B, running "pack-refs --prune", writes out the
     new packed-refs file. It then deletes the newly packed
     refs, including refs/heads/z/foo.

  3. Meanwhile, process A has finally gotten to
     refs/heads/z (it traverses alphabetically). It
     descends, but finds nothing there.  It checks its
     cached view of the packed-refs file, but it does not
     mention anything in "refs/heads/z/" at all (it predates
     the new file written by B in step 2).

The traversal completes successfully without mentioning
refs/heads/z/foo at all (the name, of course, isn't
important; but the more refs you have and the farther down
the alphabetical list a ref is, the more likely it is to hit
the race). If refs/heads/z/foo did exist in the packed refs
file at state 0, we would see an entry for it, but it would
show whatever sha1 the ref had the last time it was packed
(which could be an arbitrarily long time ago).

This can be especially dangerous when process A is "git
prune", as it means our set of reachable tips will be
incomplete, and we may erroneously prune objects reachable
from that tip (the same thing can happen if "repack -ad" is
used, as it simply drops unreachable objects that are
packed).

This patch solves it by loading all of the loose refs for
our traversal into our in-memory cache, and then refreshing
the packed-refs cache. Because a pack-refs writer will
always put the new packed-refs file into place before
starting the prune, we know that any loose refs we fail to
see will either truly be missing, or will have already been
put in the packed-refs file by the time we refresh.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-06-20 15:50:17 -07:00
Jeff King
ca9199300e get_packed_ref_cache: reload packed-refs file when it changes
Once we read the packed-refs file into memory, we cache it
to save work on future ref lookups. However, our cache may
be out of date with respect to what is on disk if another
process is simultaneously packing the refs. Normally it
is acceptable for us to be a little out of date, since there
is no guarantee whether we read the file before or after the
simultaneous update. However, there is an important special
case: our packed-refs file must be up to date with respect
to any loose refs we read. Otherwise, we risk the following
race condition:

  0. There exists a loose ref refs/heads/master.

  1. Process A starts and looks up the ref "master". It
     first checks $GIT_DIR/master, which does not exist. It
     then loads (and caches) the packed-refs file to see if
     "master" exists in it, which it does not.

  2. Meanwhile, process B runs "pack-refs --all --prune". It
     creates a new packed-refs file which contains
     refs/heads/master, and removes the loose copy at
     $GIT_DIR/refs/heads/master.

  3. Process A continues its lookup, and eventually tries
     $GIT_DIR/refs/heads/master.  It sees that the loose ref
     is missing, and falls back to the packed-refs file. But
     it examines its cached version, which does not have
     refs/heads/master. After trying a few other prefixes,
     it reports master as a non-existent ref.

There are many variants (e.g., step 1 may involve process A
looking up another ref entirely, so even a fully qualified
refname can fail). One of the most interesting ones is if
"refs/heads/master" is already packed. In that case process
A will not see it as missing, but rather will report
whatever value happened to be in the packed-refs file before
process B repacked (which might be an arbitrarily old
value).

We can fix this by making sure we reload the packed-refs
file from disk after looking at any loose refs. That's
unacceptably slow, so we can check its stat()-validity as a
proxy, and read it only when it appears to have changed.

Reading the packed-refs file after performing any loose-ref
system calls is sufficient because we know the ordering of
the pack-refs process: it always makes sure the newly
written packed-refs file is installed into place before
pruning any loose refs. As long as those operations by B
appear in their executed order to process A, by the time A
sees the missing loose ref, the new packed-refs file must be
in place.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-06-20 15:50:17 -07:00
Michael Haggerty
4f6b83e370 packed_ref_cache: increment refcount when locked
Increment the packed_ref_cache reference count while it is locked to
prevent its being freed.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-06-20 15:50:17 -07:00
Michael Haggerty
8baf2bb99a do_for_each_entry(): increment the packed refs cache refcount
This function calls a user-supplied callback function which could do
something that causes the packed refs cache to be invalidated.  So
acquire a reference count on the data structure to prevent our copy
from being freed while we are iterating over it.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-06-20 15:50:17 -07:00
Michael Haggerty
5f5e2a8868 refs: manage lifetime of packed refs cache via reference counting
In struct packed_ref_cache, keep a count of the number of users of the
data structure.  Only free the packed ref cache when the reference
count goes to zero rather than when the packed ref cache is cleared.
This mechanism will be used to prevent the cache data structure from
being freed while it is being iterated over.

So far, only the reference in struct ref_cache::packed is counted;
other users will be adjusted in separate commits.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-06-20 15:50:17 -07:00
Michael Haggerty
9f69d29770 refs: implement simple transactions for the packed-refs file
Handle simple transactions for the packed-refs file at the
packed_ref_cache level via new functions lock_packed_refs(),
commit_packed_refs(), and rollback_packed_refs().

Only allow the packed ref cache to be modified (via add_packed_ref())
while the packed refs file is locked.

Change clone to add the new references within a transaction.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-06-20 15:50:17 -07:00
Michael Haggerty
2fff781290 refs: wrap the packed refs cache in a level of indirection
As we know, we can solve any problem in this manner.  In this case,
the problem is to avoid freeing a packed refs cache while somebody is
using it.  So add a level of indirection as a prelude to
reference-counting the packed refs cache.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-06-20 15:50:17 -07:00
Michael Haggerty
267f9a8cc8 pack_refs(): split creation of packed refs and entry writing
Split pack_refs() into multiple passes:

* Iterate over loose refs.  For each one that can be turned into a
  packed ref, create a corresponding entry in the packed refs cache.

* Write the packed refs to the packed-refs file.

This change isolates the mutation of the packed-refs file to a single
place.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-06-20 15:50:17 -07:00
Michael Haggerty
7b40d39638 repack_without_ref(): split list curation and entry writing
The repack_without_ref() function first removes the deleted ref from
the internal packed-refs list, then writes the packed-refs list to
disk, omitting any broken or stale entries.  This patch splits that
second step into multiple passes:

* collect the list of refnames that should be deleted from packed_refs

* delete those refnames from the cache

* write the remainder to the packed-refs file

The purpose of this change is to make the "write the remainder" part
reusable.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-06-20 15:50:16 -07:00
Michael Haggerty
fcb7c76274 resolve_ref_unsafe(): close race condition reading loose refs
We read loose references in two steps.  The code is roughly:

    lstat()
    if error ENOENT:
        loose ref is missing; look for corresponding packed ref
    else if S_ISLNK:
        readlink()
        if error:
            report failure
    else if S_ISDIR:
        report failure
    else
        open()
        if error:
            report failure
        read()

The problem is that the first filesystem call, to lstat(), is not
atomic with the second filesystem call, to readlink() or open().
Therefore it is possible for another process to change the file
between our two calls, for example:

* If the other process deletes the file, our second call will fail
  with ENOENT, which we *should* interpret as "loose ref is missing;
  look for corresponding packed ref".  This can arise if the other
  process is pack-refs; it might have just written a new packed-refs
  file containing the old contents of the reference then deleted the
  loose ref.

* If the other process changes a symlink into a plain file, our call
  to readlink() will fail with EINVAL, which we *should* respond to by
  trying to open() and read() the file.

The old code treats the reference as missing in both of these cases,
which is incorrect.

So instead, handle errors more selectively: if the result of
readline()/open() is a failure that is inconsistent with the result of
the previous lstat(), then something is fishy.  In this case jump back
and start over again with a fresh call to lstat().

One race is still possible and undetected: another process could
change the file from a regular file into a symlink between the call to
lstat and the call to open().  The open() call would silently follow
the symlink and not know that something is wrong.  This situation
could be detected in two ways:

* On systems that support O_NOFOLLOW, pass that option to the open().

* On other systems, call fstat() on the fd returned by open() and make
  sure that it agrees with the stat info from the original lstat().

However, we don't use symlinks anymore, so this situation is unlikely.
Moreover, it doesn't appear that treating a symlink as a regular file
would have grave consequences; after all, this is exactly how the code
handles non-relative symlinks.  So this commit leaves that race
unaddressed.

Note that this solves only the part of the race within
resolve_ref_unsafe. In the situation described above, we may still be
depending on a cached view of the packed-refs file; that race will be
dealt with in a future patch.

This problem was reported and diagnosed by Jeff King <peff@peff.net>,
and this solution is derived from his patch.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Reviewed-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-06-19 10:23:04 -07:00
Michael Haggerty
2884c06ae7 resolve_ref_unsafe(): handle the case of an SHA-1 within loop
There is only one "break" statement within the loop, which jumps to
the code after the loop that handles the case of a file that holds a
SHA-1.  So move that code from below the loop into the if statement
where the break was previously located.  This makes the logic flow
more local.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Reviewed-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-06-19 10:23:03 -07:00
Michael Haggerty
47f534bf92 resolve_ref_unsafe(): extract function handle_missing_loose_ref()
The nesting was getting a bit out of hand, and it's about to get
worse.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Reviewed-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-06-19 10:23:03 -07:00
Junio C Hamano
bb1c8fbcc8 Merge branch 'fc/at-head'
Instead of typing four capital letters "HEAD", you can say "@"
instead.

* fc/at-head:
  sha1_name: compare variable with constant, not constant with variable
  Add new @ shortcut for HEAD
  sha1_name: refactor reinterpret()
  sha1_name: check @{-N} errors sooner
  sha1_name: reorganize get_sha1_basic()
  sha1_name: don't waste cycles in the @-parsing loop
  sha1_name: remove unnecessary braces
  sha1_name: remove no-op
  tests: at-combinations: @{N} versus HEAD@{N}
  tests: at-combinations: increase coverage
  tests: at-combinations: improve nonsense()
  tests: at-combinations: check ref names directly
  tests: at-combinations: simplify setup
2013-06-11 13:31:23 -07:00
Junio C Hamano
2f1ef15070 Merge branch 'mh/packed-refs-various'
Update reading and updating packed-refs file, correcting corner case
bugs.

* mh/packed-refs-various: (33 commits)
  refs: handle the main ref_cache specially
  refs: change do_for_each_*() functions to take ref_cache arguments
  pack_one_ref(): do some cheap tests before a more expensive one
  pack_one_ref(): use write_packed_entry() to do the writing
  pack_one_ref(): use function peel_entry()
  refs: inline function do_not_prune()
  pack_refs(): change to use do_for_each_entry()
  refs: use same lock_file object for both ref-packing functions
  pack_one_ref(): rename "path" parameter to "refname"
  pack-refs: merge code from pack-refs.{c,h} into refs.{c,h}
  pack-refs: rename handle_one_ref() to pack_one_ref()
  refs: extract a function write_packed_entry()
  repack_without_ref(): write peeled refs in the rewritten file
  t3211: demonstrate loss of peeled refs if a packed ref is deleted
  refs: change how packed refs are deleted
  search_ref_dir(): return an index rather than a pointer
  repack_without_ref(): silence errors for dangling packed refs
  t3210: test for spurious error messages for dangling packed refs
  refs: change the internal reference-iteration API
  refs: extract a function peel_entry()
  ...
2013-05-29 14:23:49 -07:00
Felipe Contreras
cdfd94837b Add new @ shortcut for HEAD
Typing 'HEAD' is tedious, especially when we can use '@' instead.

The reason for choosing '@' is that it follows naturally from the
ref@op syntax (e.g. HEAD@{u}), except we have no ref, and no
operation, and when we don't have those, it makes sens to assume
'HEAD'.

So now we can use 'git show @~1', and all that goody goodness.

Until now '@' was a valid name, but it conflicts with this idea, so
let's make it invalid. Probably very few people, if any, used this name.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-05-08 12:13:12 -07:00
Michael Haggerty
9da31cb027 refs: handle the main ref_cache specially
Hold the ref_cache instance for the main repository in a dedicated,
statically-allocated instance to avoid the need for a function call
and a linked-list traversal when it is needed.

Suggested by: Heiko Voigt <hvoigt@hvoigt.net>

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-05-01 15:33:11 -07:00
Michael Haggerty
65cf102bb0 refs: change do_for_each_*() functions to take ref_cache arguments
Change the callers convert submodule names into ref_cache pointers.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-05-01 15:33:11 -07:00
Michael Haggerty
b2a8226d63 pack_one_ref(): do some cheap tests before a more expensive one
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-05-01 15:33:11 -07:00
Michael Haggerty
0f29920f1e pack_one_ref(): use write_packed_entry() to do the writing
Change pack_refs() to work with a file descriptor instead of a FILE*
(making the file-locking code less awkward) and use
write_packed_entry() to do the writing.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-05-01 15:33:11 -07:00
Michael Haggerty
f85354b5c7 pack_one_ref(): use function peel_entry()
Change pack_one_ref() to call peel_entry() rather than using its own
code for peeling references.  Aside from sharing code, this lets it
take advantage of the optimization introduced by 6c4a060d7d.

Please note that we *could* use any peeled values that happen to
already be stored in the ref_entries, which would avoid some object
lookups for references that were already packed.  But doing so would
also propagate any peeling errors across runs of "git pack-refs" and
give no way to recover from such errors.  And "git pack-refs" isn't
run often enough that the performance cost is a problem.  So instead,
add a new option to peel_entry() to force the entry to be re-peeled,
and call it with that option set.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-05-01 15:33:11 -07:00
Michael Haggerty
8d3725b96f refs: inline function do_not_prune()
Function do_not_prune() was redundantly checking REF_ISSYMREF, which
was already tested at the top of pack_one_ref(), so remove that check.
And the rest was trivial, so inline the function.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-05-01 15:33:11 -07:00
Michael Haggerty
12e77559ec pack_refs(): change to use do_for_each_entry()
pack_refs() was not using any of the extra features of for_each_ref(),
so change it to use do_for_each_entry().  This also gives it access to
the ref_entry and in particular its peeled field, which will be taken
advantage of in the next commit.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-05-01 15:33:11 -07:00
Michael Haggerty
d947033037 refs: use same lock_file object for both ref-packing functions
Use a single struct lock_file for both pack_refs() and
repack_without_ref().

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-05-01 15:33:11 -07:00
Michael Haggerty
3b4ae6d502 pack_one_ref(): rename "path" parameter to "refname"
Make this function conform to the naming convention established in
65385ef7d4 for the rest of the refs.c file.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-05-01 15:33:11 -07:00
Michael Haggerty
32d462cea8 pack-refs: merge code from pack-refs.{c,h} into refs.{c,h}
pack-refs.c doesn't contain much code, and the code it does contain is
closely related to reference handling.  Moreover, there is some
duplication between pack_refs() and repack_without_ref().  Therefore,
merge pack-refs.c into refs.c and pack-refs.h into refs.h.

The code duplication will be addressed in future commits.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-05-01 15:33:11 -07:00
Michael Haggerty
fec3137ffc refs: extract a function write_packed_entry()
Extract the I/O code from the "business logic" in repack_ref_fn().
Later there will be another caller for this function.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-05-01 15:33:10 -07:00
Michael Haggerty
694b7a1999 repack_without_ref(): write peeled refs in the rewritten file
When a reference that existed in the packed-refs file is deleted, the
packed-refs file must be rewritten.  Previously, the file was
rewritten without any peeled refs, even if the file contained peeled
refs when it was read.  This was not a bug, because the packed-refs
file header didn't claim that the file contained peeled values.  But
it had a performance cost, because the repository would lose the
benefit of having precomputed peeled references until pack-refs was
run again.

Teach repack_without_ref() to write peeled refs to the packed-refs
file (regardless of whether they were present in the old version of
the file).

This means that if the old version of the packed-refs file was not
fully peeled, then repack_without_ref() will have to peel references.
To avoid the expense of reading lots of loose references, we take two
shortcuts relative to pack-refs:

* If the peeled value of a reference is already known (i.e., because
  it was read from the old version of the packed-refs file), then
  output that peeled value again without any checks.  This is the
  usual code path and should avoid any noticeable overhead.  (This is
  different than pack-refs, which always re-peels references.)

* We don't verify that the packed ref is still current.  It could be
  that a packed references is overridden by a loose reference, in
  which case the packed ref is no longer needed and might even refer
  to an object that has been garbage collected.  But we don't check;
  instead, we just try to peel all references.  If peeling is
  successful, the peeled value is written out (even though it might
  not be needed any more); if not, then the reference is silently
  omitted from the output.

The extra overhead of peeling references in repack_without_ref()
should only be incurred the first time the packed-refs file is written
by a version of Git that knows about the "fully-peeled" attribute.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-05-01 15:33:10 -07:00
Michael Haggerty
506a760db8 refs: change how packed refs are deleted
Add a function remove_ref(), which removes a single entry from a
reference cache.

Use this function to reimplement repack_without_ref().  The old
version iterated over all refs, packing all of them except for the one
to be deleted, then discarded the entire packed reference cache.  The
new version deletes the doomed reference from the cache *before*
iterating.

This has two advantages:

* the code for writing packed-refs becomes simpler, because it doesn't
  have to exclude one of the references.

* it is no longer necessary to discard the packed refs cache after
  deleting a reference: symbolic refs cannot be packed, so packed
  references cannot depend on each other, so the rest of the packed
  refs cache remains valid after a reference is deleted.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-05-01 15:33:10 -07:00
Michael Haggerty
9fc0a64806 search_ref_dir(): return an index rather than a pointer
Change search_ref_dir() to return the index of the sought entry (or -1
on error) rather than a pointer to the entry.  This will make it more
natural to use the function for removing an entry from the list.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-05-01 15:33:10 -07:00
Michael Haggerty
ab292bc4f3 repack_without_ref(): silence errors for dangling packed refs
Stop emitting an error message when deleting a packed reference if we
find another dangling packed reference that is overridden by a loose
reference.  See the previous commit for a longer explanation of the
issue.

We have to be careful to make sure that the invalid packed reference
really *is* overridden by a loose reference; otherwise what we have
found is repository corruption, which we *should* report.

Please note that this approach is vulnerable to a race condition
similar to the race conditions already known to affect packed
references [1]:

* Process 1 tries to peel packed reference X as part of deleting
  another packed reference.  It discovers that X does not refer to a
  valid object (because the object that it referred to has been
  garbage collected).

* Process 2 tries to delete reference X.  It starts by deleting the
  loose reference X.

* Process 1 checks whether there is a loose reference X.  There is not
  (it has just been deleted by process 2), so process 1 reports a
  spurious error "X does not point to a valid object!"

The worst case seems relatively harmless, and the fix is identical to
the fix that will be needed for the other race conditions (namely
holding a lock on the packed-refs file during *all* reference
deletions), so we leave the cleaning up of all of them as a future
project.

[1] http://thread.gmane.org/gmane.comp.version-control.git/211956

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-05-01 15:33:10 -07:00
Michael Haggerty
624cac3514 refs: change the internal reference-iteration API
Establish an internal API for iterating over references, which gives
the callback functions direct access to the ref_entry structure
describing the reference.  (Do not change the iteration API that is
exposed outside of the module.)

Define a new internal callback signature

   int each_ref_entry_fn(struct ref_entry *entry, void *cb_data)

Change do_for_each_ref_in_dir() and do_for_each_ref_in_dirs() to
accept each_ref_entry_fn callbacks, and rename them to
do_for_each_entry_in_dir() and do_for_each_entry_in_dirs(),
respectively.  Adapt their callers accordingly.

Add a new function do_for_each_entry() analogous to do_for_each_ref()
but using the new callback style.

Change do_one_ref() into an each_ref_entry_fn that does some
bookkeeping and then calls a wrapped each_ref_fn.

Reimplement do_for_each_ref() in terms of do_for_each_entry(), using
do_one_ref() as an adapter.

Please note that the responsibility for setting current_ref remains in
do_one_ref(), which means that current_ref is *not* set when iterating
over references via the new internal API.  This is not a disadvantage,
because current_ref is not needed by callers of the internal API (they
receive a pointer to the current ref_entry anyway).  But more
importantly, this change prevents peel_ref() from returning invalid
results in the following scenario:

When iterating via the external API, the iteration always includes
both packed and loose references, and in particular never presents a
packed ref if there is a loose ref with the same name.  The internal
API, on the other hand, gives the option to iterate over only the
packed references.  During such an iteration, there is no check
whether the packed ref might be hidden by a loose ref of the same
name.  But until now the packed ref was recorded in current_ref during
the iteration.  So if peel_ref() were called with the reference name
corresponding to current ref, it would return the peeled version of
the packed ref even though there might be a loose ref that peels to a
different value.  This scenario doesn't currently occur in the code,
but fix it to prevent things from breaking in a very confusing way in
the future.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-05-01 15:33:10 -07:00
Michael Haggerty
9a489f3c17 refs: extract a function peel_entry()
Peel the entry, and as a side effect store the peeled value in the
entry.  Use this function from two places in peel_ref(); a third
caller will be added soon.

Please note that this change can lead to ref_entries for unpacked refs
being peeled.  This has no practical benefit but is harmless.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-05-01 15:33:10 -07:00
Michael Haggerty
2312a79320 peel_ref(): fix return value for non-peelable, not-current reference
The old version was inconsistent: when a reference was
REF_KNOWS_PEELED but with a null peeled value, it returned non-zero
for the current reference but zero for other references.  Change the
behavior for non-current references to match that of current_ref,
which is what callers expect.  Document the behavior.

Current callers only call peel_ref() from within a for_each_ref-style
iteration and only for the current ref; therefore, the buggy code path
was never reached.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-05-01 15:33:10 -07:00
Michael Haggerty
68cf870344 peel_object(): give more specific information in return value
Instead of just returning a success/failure bit, return an enumeration
value that explains the reason for any failure.  This will come in
handy shortly.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-05-01 15:33:10 -07:00
Michael Haggerty
cb2ae1c418 refs: extract function peel_object()
It is a nice, logical unit of work, and putting it in a function
removes the need to use a goto in peel_ref().  Soon it will also have
other uses.

The algorithm is unchanged.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-05-01 15:33:10 -07:00
Michael Haggerty
662428f4e9 refs: extract a function ref_resolves_to_object()
It is a nice unit of work and soon will be needed from multiple
locations.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-05-01 15:33:10 -07:00
Michael Haggerty
7618fd808a repack_without_ref(): use function get_packed_ref()
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-05-01 15:33:09 -07:00
Michael Haggerty
f361baeb71 peel_ref(): use function get_packed_ref()
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-05-01 15:33:09 -07:00
Michael Haggerty
63331581ab get_packed_ref(): return a ref_entry
Instead of copying the reference's SHA1 into a caller-supplied
variable, just return the ref_entry itself (or NULL if there is no
such entry).  This change will allow the function to be used from
elsewhere.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-05-01 15:33:09 -07:00
Michael Haggerty
b830f6c66b do_for_each_ref_in_dirs(): remove dead code
There is no way to drop out of the while loop.  This code has been
dead since 432ad41e.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-05-01 15:33:09 -07:00
Michael Haggerty
3feb4f0cfb refs: define constant PEELED_LINE_LENGTH
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-05-01 15:33:09 -07:00
Michael Haggerty
7d76fdc829 refs: document how current_ref is used
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-05-01 15:33:09 -07:00
Michael Haggerty
fcce17039c refs: document do_for_each_ref() and do_one_ref()
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-05-01 15:33:09 -07:00
Michael Haggerty
6c6f58dfd2 refs: document the fields of struct ref_value
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-05-01 15:33:09 -07:00
Michael Haggerty
89df9c84e4 refs: document flags constants REF_*
Document the bits that can appear in the "flags" parameter passed to
an each_ref_function and/or in the ref_entry::flag field.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-05-01 15:33:09 -07:00
Junio C Hamano
f1ad05f3a5 Merge branch 'jk/fully-peeled-packed-ref' into maint-1.8.1
* jk/fully-peeled-packed-ref:
  pack-refs: add fully-peeled trait
  pack-refs: write peeled entry for non-tags
  use parse_object_or_die instead of die("bad object")
  avoid segfaults on parse_object failure
2013-04-03 08:43:03 -07:00
Junio C Hamano
6beb484f25 Merge branch 'jc/reflog-reverse-walk'
An internal function used to implement "git checkout @{-1}" was
hard to use correctly.

* jc/reflog-reverse-walk:
  refs.c: fix fread error handling
  reflog: add for_each_reflog_ent_reverse() API
  for_each_recent_reflog_ent(): simplify opening of a reflog file
  for_each_reflog_ent(): extract a helper to process a single entry
2013-03-26 13:15:56 -07:00
Junio C Hamano
870987dec7 Merge branch 'jk/fully-peeled-packed-ref'
Not that we do not actively encourage having annotated tags outside
refs/tags/ hierarchy, but they were not advertised correctly to the
ls-remote and fetch with recent version of Git.

* jk/fully-peeled-packed-ref:
  pack-refs: add fully-peeled trait
  pack-refs: write peeled entry for non-tags
  use parse_object_or_die instead of die("bad object")
  avoid segfaults on parse_object failure
2013-03-25 14:01:07 -07:00
John Keeping
e4ca819abf refs.c: fix fread error handling
fread returns the number of items read, with no special error return.

Commit 98f85ff (reflog: add for_each_reflog_ent_reverse() API -
2013-03-08) introduced a call to fread which checks for an error with
"nread < 0" which is tautological since nread is unsigned.  The correct
check in this case (which tries to read a single item) is "nread != 1".

Signed-off-by: John Keeping <john@keeping.me.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-03-23 23:50:50 -07:00
Michael Haggerty
c29c46fa2e pack-refs: add fully-peeled trait
Older versions of pack-refs did not write peel lines for
refs outside of refs/tags. This meant that on reading the
pack-refs file, we might set the REF_KNOWS_PEELED flag for
such a ref, even though we do not know anything about its
peeled value.

The previous commit updated the writer to always peel, no
matter what the ref is. That means that packed-refs files
written by newer versions of git are fine to be read by both
old and new versions of git. However, we still have the
problem of reading packed-refs files written by older
versions of git, or by other implementations which have not
yet learned the same trick.

The simplest fix would be to always unset the
REF_KNOWS_PEELED flag for refs outside of refs/tags that do
not have a peel line (if it has a peel line, we know it is
valid, but we cannot assume a missing peel line means
anything). But that loses an important optimization, as
upload-pack should not need to load the object pointed to by
refs/heads/foo to determine that it is not a tag.

Instead, we add a "fully-peeled" trait to the packed-refs
file. If it is set, we know that we can trust a missing peel
line to mean that a ref cannot be peeled. Otherwise, we fall
back to assuming nothing.

[commit message and tests by Jeff King <peff@peff.net>]

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-03-18 08:06:28 -07:00
Junio C Hamano
98f85ff4b6 reflog: add for_each_reflog_ent_reverse() API
"git checkout -" is a short-hand for "git checkout @{-1}" and the
"@{nth}" notation for a negative number is to find nth previous
checkout in the reflog of the HEAD to determine the name of the
branch the user was on.  We would want to find the nth most recent
reflog entry that matches "checkout: moving from X to Y" for this.

Unfortunately, reflog is implemented as an append-only file, and the
API to iterate over its entries, for_each_reflog_ent(), reads the
file in order, giving the entries from the oldest to newer.  For the
purpose of finding nth most recent one, this API forces us to record
the last n entries in a rotating buffer and give the result out only
after we read everything.  To optimize for a common case of finding
the nth most recent one for a small value of n, we also have a side
API for_each_recent_reflog_ent() that starts reading near the end of
the file, but it still has to read the entries in the "wrong" order.
The implementation of understanding @{-1} uses this interface.

This all becomes unnecessary if we add an API to let us iterate over
reflog entries in the reverse order, from the newest to older.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-03-08 14:00:22 -08:00
Junio C Hamano
7ae07c1bd7 for_each_recent_reflog_ent(): simplify opening of a reflog file
There is no reason to use a temporary variable logfile.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-03-08 14:00:16 -08:00
Junio C Hamano
9a7a183bd2 for_each_reflog_ent(): extract a helper to process a single entry
Split the logic that takes a single line of reflog entry in a
strbuf, parses the message, and calls the callback function out of
the loop into a separate helper function.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-03-08 13:59:57 -08:00
Junio C Hamano
ce735bf7fd Merge branch 'jc/hidden-refs'
Allow the server side to redact the refs/ namespace it shows to the
client.

Will merge to 'master'.

* jc/hidden-refs:
  upload/receive-pack: allow hiding ref hierarchies
  upload-pack: simplify request validation
  upload-pack: share more code
2013-02-17 15:25:57 -08:00
Junio C Hamano
daebaa7813 upload/receive-pack: allow hiding ref hierarchies
A repository may have refs that are only used for its internal
bookkeeping purposes that should not be exposed to the others that
come over the network.

Teach upload-pack to omit some refs from its initial advertisement
by paying attention to the uploadpack.hiderefs multi-valued
configuration variable.  Do the same to receive-pack via the
receive.hiderefs variable.  As a convenient short-hand, allow using
transfer.hiderefs to set the value to both of these variables.

Any ref that is under the hierarchies listed on the value of these
variable is excluded from responses to requests made by "ls-remote",
"fetch", etc. (for upload-pack) and "push" (for receive-pack).

Because these hidden refs do not count as OUR_REF, an attempt to
fetch objects at the tip of them will be rejected, and because these
refs do not get advertised, "git push :" will not see local branches
that have the same name as them as "matching" ones to be sent.

An attempt to update/delete these hidden refs with an explicit
refspec, e.g. "git push origin :refs/hidden/22", is rejected.  This
is not a new restriction.  To the pusher, it would appear that there
is no such ref, so its push request will conclude with "Now that I
sent you all the data, it is time for you to update the refs.  I saw
that the ref did not exist when I started pushing, and I want the
result to point at this commit".  The receiving end will apply the
compare-and-swap rule to this request and rejects the push with
"Well, your update request conflicts with somebody else; I see there
is such a ref.", which is the right thing to do. Otherwise a push to
a hidden ref will always be "the last one wins", which is not a good
default.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-02-07 13:48:47 -08:00
Junio C Hamano
f12e49ae87 Merge branch 'rs/clarify-entry-cmp-sslice'
* rs/clarify-entry-cmp-sslice:
  refs: use strncmp() instead of strlen() and memcmp()
2013-01-23 21:19:06 -08:00
René Scharfe
c971ddfdcd refs: use strncmp() instead of strlen() and memcmp()
Simplify ref_entry_cmp_sslice() by using strncmp() to compare the
length-limited key and a NUL-terminated entry.  While we're at it,
retain the const attribute of the input pointers.

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-01-16 09:48:36 -08:00
Junio C Hamano
f70eec8400 Merge branch 'jk/repack-ref-racefix' into maint
* jk/repack-ref-racefix:
  refs: do not use cached refs in repack_without_ref
2013-01-10 14:04:17 -08:00
Junio C Hamano
229096a591 Merge branch 'jk/repack-ref-racefix'
"git pack-refs" that ran in parallel to another process that created
new refs had a nasty race.

* jk/repack-ref-racefix:
  refs: do not use cached refs in repack_without_ref
2013-01-02 10:39:37 -08:00
Jeff King
b3f1280ec7 refs: do not use cached refs in repack_without_ref
When we delete a ref that is packed, we rewrite the whole
packed-refs file and simply omit the ref that no longer
exists. However, we base the rewrite on whatever happens to
be in our refs cache, not what is necessarily on disk. That
opens us up to a race condition if another process is
simultaneously packing the refs, as we will overwrite their
newly-made pack-refs file with our potentially stale data,
losing commits.

You can demonstrate the race like this:

  # setup some repositories
  git init --bare parent &&
  (cd parent && git config core.logallrefupdates true) &&
  git clone parent child &&
  (cd child && git commit --allow-empty -m base)

  # in one terminal, repack the refs repeatedly
  cd parent &&
  while true; do
	git pack-refs --all
  done

  # in another terminal, simultaneously push updates to
  # master, and create and delete an unrelated ref
  cd child &&
  while true; do
	git push origin HEAD:newbranch &&
	git commit --allow-empty -m foo
	us=`git rev-parse master` &&
	git push origin master &&
	git push origin :newbranch &&
	them=`git --git-dir=../parent rev-parse master` &&
	if test "$them" != "$us"; then
		echo >&2 "$them" != "$us"
		exit 1
	fi
  done

In many cases the two processes will conflict over locking
the packed-refs file, and the deletion of newbranch will
simply fail.  But eventually you will hit the race, which
happens like this:

  1. We push a new commit to master. It is already packed
     (from the looping pack-refs call). We write the new
     value (let us call it B) to $GIT_DIR/refs/heads/master,
     but the old value (call it A) remains in the
     packed-refs file.

  2. We push the deletion of newbranch, spawning a
     receive-pack process. Receive-pack advertises all refs
     to the client, causing it to iterate over each ref; it
     caches the packed refs in memory, which points at the
     stale value A.

  3. Meanwhile, a separate pack-refs process is running. It
     runs to completion, updating the packed-refs file to
     point master at B, and deleting $GIT_DIR/refs/heads/master
     which also pointed at B.

  4. Back in the receive-pack process, we get the
     instruction to delete :newbranch. We take a lock on
     packed-refs (which works, as the other pack-refs
     process has already finished). We then rewrite the
     contents using the cached refs, which contain the stale
     value A.

The resulting packed-refs file points master once again at
A. The loose ref which would override it to point at B was
deleted (rightfully) in step 3. As a result, master now
points at A. The only trace that B ever existed in the
parent is in the reflog: the final entry will show master
moving from A to B, even though the ref still points at A
(so you can detect this race after the fact, because the
next reflog entry will move from A to C).

We can fix this by invalidating the packed-refs cache after
we have taken the lock. This means that we will re-read the
packed-refs file, and since we have the lock, we will be
sure that what we read will be atomically up-to-date when we
write (it may be out of date with respect to loose refs, but
that is OK, as loose refs take precedence).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-12-21 08:10:22 -08:00
Junio C Hamano
cf22e272e4 Merge branch 'jh/update-ref-d-through-symref'
"update-ref -d --deref SYM" to delete a ref through a symbolic ref
that points to it did not remove it correctly.

* jh/update-ref-d-through-symref:
  Fix failure to delete a packed ref through a symref
  t1400-update-ref: Add test verifying bug with symrefs in delete_ref()
2012-11-25 18:44:17 -08:00
Jeff King
15ba878a1d Merge branch 'rs/lock-correct-ref-during-delete'
When "update-ref -d --no-deref SYM" tried to delete a symbolic ref
SYM, it incorrectly locked the underlying reference pointed by SYM,
not the symbolic ref itself.

* rs/lock-correct-ref-during-delete:
  refs: lock symref that is to be deleted, not its target
2012-11-09 12:42:28 -05:00
Johan Herland
b274a7146c Fix failure to delete a packed ref through a symref
When deleting a ref through a symref (e.g. using 'git update-ref -d HEAD'
to delete refs/heads/master), we would remove the loose ref, but a packed
version of the same ref would remain, the end result being that instead of
deleting refs/heads/master we would appear to reset it to its state as of
the last repack.

This patch fixes the issue, by making sure we pass the correct ref name
when invoking repack_without_ref() from within delete_ref().

Signed-off-by: Johan Herland <johan@herland.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-10-21 12:08:42 -07:00
René Scharfe
547d058fb6 refs: lock symref that is to be deleted, not its target
When delete_ref is called on a symref then it locks its target and then
either deletes the target or the symref, depending on whether the flag
REF_NODEREF was set in the parameter delopt.

Instead, simply pass the flag to lock_ref_sha1_basic, which will then
either lock the target or the symref, and delete the locked ref.

This reimplements part of eca35a25 (Fix git branch -m for symrefs.).

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-10-16 10:08:23 -07:00
Jeff King
6c4a060d7d peel_ref: check object type before loading
The point of peel_ref is to dereference tags; if the base
object is not a tag, then we can return early without even
loading the object into memory.

This patch accomplishes that by checking sha1_object_info
for the type. For a packed object, we can get away with just
looking in the pack index. For a loose object, we only need
to inflate the first couple of header bytes.

This is a bit of a gamble; if we do find a tag object, then
we will end up loading the content anyway, and the extra
lookup will have been wasteful. However, if it is not a tag
object, then we save loading the object entirely. Depending
on the ratio of non-tags to tags in the input, this can be a
minor win or minor loss.

However, it does give us one potential major win: if a ref
points to a large blob (e.g., via an unannotated tag), then
we can avoid looking at it entirely.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-10-04 20:34:28 -07:00
Jeff King
e6dbffa67b peel_ref: do not return a null sha1
The idea of the peel_ref function is to dereference tag
objects recursively until we hit a non-tag, and return the
sha1. Conceptually, it should return 0 if it is successful
(and fill in the sha1), or -1 if there was nothing to peel.

However, the current behavior is much more confusing. For a
regular loose ref, the behavior is as described above. But
there is an optimization to reuse the peeled-ref value for a
ref that came from a packed-refs file. If we have such a
ref, we return its peeled value, even if that peeled value
is null (indicating that we know the ref definitely does
_not_ peel).

It might seem like such information is useful to the caller,
who would then know not to bother loading and trying to peel
the object. Except that they should not bother loading and
trying to peel the object _anyway_, because that fallback is
already handled by peel_ref. In other words, the whole point
of calling this function is that it handles those details
internally, and you either get a sha1, or you know that it
is not peel-able.

This patch catches the null sha1 case internally and
converts it into a -1 return value (i.e., there is nothing
to peel). This simplifies callers, which do not need to
bother checking themselves.

Two callers are worth noting:

  - in pack-objects, a comment indicates that there is a
    difference between non-peelable tags and unannotated
    tags. But that is not the case (before or after this
    patch). Whether you get a null sha1 has to do with
    internal details of how peel_ref operated.

  - in show-ref, if peel_ref returns a failure, the caller
    tries to decide whether to try peeling manually based on
    whether the REF_ISPACKED flag is set. But this doesn't
    make any sense. If the flag is set, that does not
    necessarily mean the ref came from a packed-refs file
    with the "peeled" extension. But it doesn't matter,
    because even if it didn't, there's no point in trying to
    peel it ourselves, as peel_ref would already have done
    so. In other words, the fallback peeling is guaranteed
    to fail.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-10-04 20:34:28 -07:00
Jeff King
44da6f69ec peel_ref: use faster deref_tag_noverify
When we are asked to peel a ref to a sha1, we internally call
deref_tag, which will recursively parse each tagged object
until we reach a non-tag. This has the benefit that we will
verify our ability to load and parse the pointed-to object.

However, there is a performance downside: we may not need to
load that object at all (e.g., if we are listing peeled
simply listing peeled refs), or it may be a large object
that should follow a streaming code path (e.g., an annotated
tag of a large blob).

It makes more sense for peel_ref to choose the fast thing
rather than performing the extra check, for two reasons:

  1. We will already sometimes short-circuit the tag parsing
     in favor of a peeled entry from a packed-refs file. So
     we are already favoring speed in some cases, and it is
     not wise for a caller to rely on peel_ref to detect
     corruption.

  2. We already silently ignore much larger corruptions,
     like a ref that points to a non-existent object, or a
     tag object that exists but is corrupted.

  2. peel_ref is not the right place to check for such a
     database corruption. It is returning only the sha1
     anyway, not the actual object. Any callers which use
     that sha1 to load an object will soon discover the
     corruption anyway, so we are really just pushing back
     the discovery to later in the program.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-10-04 20:34:28 -07:00
Junio C Hamano
a7060009e1 Merge branch 'rs/refs-string-slice'
Avoid unnecessary temporary allocations while looking for matching refs
inside refs API.

By René Scharfe (3) and Junio C Hamano (1)
* rs/refs-string-slice:
  refs: do not create ref_entry when searching
  refs: use strings directly in find_containing_dir()
  refs: convert parameter of create_dir_entry() to length-limited string
  refs: convert parameter of search_ref_dir() to length-limited string
2012-05-29 13:09:02 -07:00
Junio C Hamano
38f2b874ff Merge branch 'mh/ref-api-lazy-loose'
The code to lazily read loose refs unnecessarily read the refs in a
subhierarchy by mistake when we free the data for the subhierarchy.

By Michael Haggerty
* mh/ref-api-lazy-loose:
  free_ref_entry(): do not trigger reading of loose refs
2012-05-29 13:08:35 -07:00
Junio C Hamano
ec04a275b4 Merge branch 'mh/ref-api'
Fixes a performance regression in the earlier series.
2012-05-25 12:04:36 -07:00
Michael Haggerty
654ad400c2 Avoid sorting if references are added to ref_cache in order
The old code allowed many references to be efficiently added to a
single directory, because it just appended the references to the
containing directory unsorted without doing any searching (and
therefore without requiring any intermediate sorting).  But the old
code was inefficient when a large number of subdirectories were added
to a directory, because the directory always had to be searched to see
if the new subdirectory already existed, and this search required the
directory to be sorted first.  The same was repeated for every new
subdirectory, so the time scaled like O(N^2), where N is the number of
subdirectories within a single directory.

In practice, references are often added to the ref_cache in
lexicographic order, for example when reading the packed-refs file.
So build some intelligence into add_entry_to_dir() to optimize for the
case of references and/or subdirectories being added in lexicographic
order: if the existing entries were already sorted, and the new entry
comes after the last existing entry, then adjust ref_dir::sorted to
reflect the fact that the ref_dir is still sorted.

Thanks to Peff for pointing out the performance regression that
inspired this change.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-05-24 12:16:06 -07:00
Junio C Hamano
e1980c9d23 refs: do not create ref_entry when searching
The search_ref_dir() function is about looking up an existing ref_entry in
a sorted array of ref_entry stored in dir->entries, but it still allocates
a new ref_entry and frees it before returning.  This is only because the
call to bsearch(3) was coded in a suboptimal way. Unlike the comparison
function given to qsort(3), the first parameter to its comparison function
does not need to point at an object that is shaped like an element in the
array.

Introduce a new comparison function that takes a counted string as the key
and an element in an array of ref_entry and give it to bsearch(), so that
we do not have to allocate a new ref_entry that we will never return to
the caller anyway.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-05-22 14:28:03 -07:00
René Scharfe
dd02e72852 refs: use strings directly in find_containing_dir()
Convert the parameter subdirname of search_for_subdir() to a
length-limted string and then simply pass the interesting slice of the
refname from find_containing_dir(), thereby avoiding to duplicate the
string.

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-05-22 13:32:26 -07:00
René Scharfe
b9146f517a refs: convert parameter of create_dir_entry() to length-limited string
Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-05-22 13:32:24 -07:00
René Scharfe
40ad937d47 refs: convert parameter of search_ref_dir() to length-limited string
Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-05-22 13:32:21 -07:00
Michael Haggerty
27b5587c76 free_ref_entry(): do not trigger reading of loose refs
Do not call get_ref_dir() from within free_ref_entry(), because that
triggers the reading of loose refs, only for them to be freed
immediately.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-05-20 15:10:49 -07:00
Junio C Hamano
aa6912b081 Merge branch 'mh/ref-api-lazy-loose'
Refs API is updated to lazily read sub-hierarchies of refs/ namespace,
so that we do not have to grab everything from the filesystem when we
are only interested in listing branches, for example.

By Michael Haggerty (17) and Junio C Hamano (1)
* mh/ref-api-lazy-loose:
  refs: fix find_containing_dir() regression
  refs: read loose references lazily
  read_loose_refs(): eliminate ref_cache argument
  struct ref_dir: store a reference to the enclosing ref_cache
  search_for_subdir(): return (ref_dir *) instead of (ref_entry *)
  get_ref_dir(): add function for getting a ref_dir from a ref_entry
  read_loose_refs(): rename function from get_ref_dir()
  refs: wrap top-level ref_dirs in ref_entries
  find_containing_dir(): use strbuf in implementation of this function
  bisect: copy filename string obtained from git_path()
  do_for_each_reflog(): use a strbuf to hold logfile name
  do_for_each_reflog(): return early on error
  get_ref_dir(): take the containing directory as argument
  refs.c: extract function search_for_subdir()
  get_ref_dir(): require that the dirname argument ends in '/'
  get_ref_dir(): rename "base" parameter to "dirname"
  get_ref_dir(): use a strbuf to hold refname
  get_ref_dir(): return early if directory cannot be read
2012-05-10 10:49:08 -07:00
Junio C Hamano
663c1295d8 refs: fix find_containing_dir() regression
The function used to return NULL when asked to find the containing
directory for a ref that does not exist, allowing the caller to
omit iteration altogether. But a misconversion in an earlier change
"refs.c: extract function search_for_subdir()" started returning the
top-level directory entry, forcing callers to walk everything.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-05-04 09:17:50 -07:00
Michael Haggerty
28e6a34e25 refs: read loose references lazily
Instead of reading the whole directory of loose references the first
time any are needed, only read them on demand, one directory at a
time.

Use a new ref_entry flag bit REF_INCOMPLETE to indicate that the entry
represents a REF_DIR that hasn't been read yet.  Whenever any entries
from such a directory are needed, read all of the loose references
from that directory.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-05-03 13:15:36 -07:00
Michael Haggerty
423a1afc0b read_loose_refs(): eliminate ref_cache argument
The ref_cache can now be read from the ref_dir.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-05-03 13:15:36 -07:00
Michael Haggerty
f006c42a11 struct ref_dir: store a reference to the enclosing ref_cache
This means that a directory ref_entry contains all of the information
needed by read_loose_refs().

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-05-03 13:15:36 -07:00
Michael Haggerty
3f3aa1bc62 search_for_subdir(): return (ref_dir *) instead of (ref_entry *)
That is what all the callers want, so give it to them.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-05-03 13:15:36 -07:00
Michael Haggerty
d7826d5427 get_ref_dir(): add function for getting a ref_dir from a ref_entry
Convert all accesses of a ref_dir within a ref_entry to use this
function.  This function will later be responsible for reading loose
references from disk on demand.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-05-03 13:15:36 -07:00
Michael Haggerty
1900b976a4 read_loose_refs(): rename function from get_ref_dir()
The new name better describes the function's purpose, and also makes
the old name available for a more suitable purpose.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-05-03 13:15:36 -07:00
Michael Haggerty
d12229f532 refs: wrap top-level ref_dirs in ref_entries
Make it turtles all the way down.  This affects the loose and packed
fields of ref_cache instances.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-05-03 13:15:35 -07:00
Michael Haggerty
5fa0441844 find_containing_dir(): use strbuf in implementation of this function
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-05-03 13:15:35 -07:00
Michael Haggerty
989c0e5d02 do_for_each_reflog(): use a strbuf to hold logfile name
This simplifies the bookkeeping and allows an (artificial) restriction
on refname component length to be removed.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-05-03 13:15:35 -07:00
Michael Haggerty
93c603fcb7 do_for_each_reflog(): return early on error
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-05-03 13:15:09 -07:00
Michael Haggerty
9f2fb4a373 get_ref_dir(): take the containing directory as argument
Previously, the "dir" argument to get_ref_dir() was a pointer to the
top-level ref_dir.  Change the function to expect a pointer to the
ref_dir corresponding to dirname.  This allows entries to be added
directly to dir, without having to recurse through the reference trie
each time (i.e., we can use add_entry_to_dir() instead of add_ref()).

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-05-03 13:15:09 -07:00
Michael Haggerty
f348ac923c refs.c: extract function search_for_subdir()
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-05-03 13:15:09 -07:00
Michael Haggerty
abc390989f get_ref_dir(): require that the dirname argument ends in '/'
This removes some conditional code and makes it consistent with the
way that direntry names are stored.  Please note that this function is
never used on the top-level .git directory; it is always called for
directories at level .git/refs or deeper.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-05-03 13:15:09 -07:00
Michael Haggerty
66a3d20b8f get_ref_dir(): rename "base" parameter to "dirname"
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-05-03 13:15:09 -07:00
Michael Haggerty
72b64b44e7 get_ref_dir(): use a strbuf to hold refname
This simplifies the bookkeeping and allows an (artificial) restriction
on refname component length to be removed.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-05-03 13:15:09 -07:00
Junio C Hamano
1be65eda6a Merge branch 'nd/i18n'
More message strings marked for i18n.

By Nguyễn Thái Ngọc Duy (10) and Jonathan Nieder (1)
* nd/i18n:
  help: replace underlining "help -a" headers using hyphens with a blank line
  i18n: bundle: mark strings for translation
  i18n: index-pack: mark strings for translation
  i18n: apply: update say_patch_name to give translators complete sentence
  i18n: apply: mark strings for translation
  i18n: remote: mark strings for translation
  i18n: make warn_dangling_symref() automatically append \n
  i18n: help: mark strings for translation
  i18n: mark relative dates for translation
  strbuf: convenience format functions with \n automatically appended
  Makefile: feed all header files to xgettext
2012-05-02 13:51:35 -07:00
Michael Haggerty
d5fdae6737 get_ref_dir(): return early if directory cannot be read
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-04-25 10:43:20 -07:00
Nguyễn Thái Ngọc Duy
18986d5377 i18n: make warn_dangling_symref() automatically append \n
This helps remove \n from translatable strings

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-04-24 14:55:48 -07:00
Michael Haggerty
933ac036d2 do_for_each_ref(): only iterate over the subtree that was requested
If the base argument has a "/" chararacter, then only iterate over the
reference subdir whose name is the part up to the last "/".

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-04-10 15:55:55 -07:00
Michael Haggerty
432ad41e60 refs: store references hierarchically
Store references hierarchically in a tree that matches the
pseudo-directory structure of the reference names.  Add a new kind of
ref_entry (with flag REF_DIR) to represent a whole subdirectory of
references.  Sort ref_dirs one subdirectory at a time.

NOTE: the dirs can now be sorted as a side-effect of other function
calls.  Therefore, it would be problematic to do something from a
each_ref_fn callback that could provoke the sorting of a directory
that is currently being iterated over (i.e., the directory containing
the entry that is being processed or any of its parents).

This is a bit far-fetched, because a directory is always sorted just
before being iterated over.  Therefore, read-only accesses cannot
trigger the sorting of a directory whose iteration has already
started.  But if a callback function would add a reference to a parent
directory of the reference in the iteration, then try to resolve a
reference under that directory, a re-sort could be triggered and cause
the iteration to work incorrectly.

Nevertheless...add a comment in refs.h warning against modifications
during iteration.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-04-10 15:55:55 -07:00
Michael Haggerty
81a79d8e27 sort_ref_dir(): simplify logic
Use the more usual indexing idiom for clarity.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-04-10 15:55:50 -07:00
Michael Haggerty
d3177275ed refs.c: rename ref_array -> ref_dir
This purely textual change is in preparation for storing references
hierarchically, when the old ref_array structure will represent one
"directory" of references.  Rename functions that deal with this
structure analogously, and also rename the structure's "refs" member
to "entries".

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-04-10 15:54:59 -07:00
Michael Haggerty
593f1bb82f struct ref_entry: nest the value part in a union
This change is obviously silly by itself, but it is a step towards
adding a second member to the union.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-04-10 15:54:58 -07:00
Michael Haggerty
dac529e44f check_refname_component(): return 0 for zero-length components
Return 0 (instead of -1) for zero-length components.  Move the
interpretation of zero-length components as illegal to
check_refname_format().

This will make it easier to extend check_refname_format() to also
check whether directory names are valid.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-04-10 15:54:58 -07:00
Michael Haggerty
732134edab free_ref_entry(): new function
Add a function free_ref_entry().  This function will become nontrivial
when ref_entry (soon) becomes polymorphic.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-04-10 15:54:58 -07:00
Michael Haggerty
5a4d494731 names_conflict(): simplify implementation
Save a bunch of lines of code and a couple of strlen() calls.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-04-10 15:54:54 -07:00
Michael Haggerty
d66da478f2 repack_without_ref(): reimplement using do_for_each_ref_in_array()
It costs a bit of boilerplate, but it means that the function can be
ignorant of how cached refs are stored.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-04-10 15:53:28 -07:00
Michael Haggerty
b3fd060f9e do_for_each_ref_in_arrays(): new function
Extract function do_for_each_ref_in_arrays() from do_for_each_ref().
The new function will be a useful building block for storing refs
hierarchically.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-04-10 15:51:52 -07:00
Michael Haggerty
c36b5bc2e4 do_for_each_ref_in_array(): new function
Extract function do_for_each_ref_in_array() from do_for_each_ref().
The new function will be a useful building block for storing refs
hierarchically.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-04-10 15:51:52 -07:00
Michael Haggerty
429213e470 refs: manage current_ref within do_one_ref()
Set and clear current_ref within do_one_ref() instead of setting it
here and leaving it to somebody else to clear it.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-04-10 15:51:52 -07:00
Michael Haggerty
bc5fd6d3c2 refs.c: reorder definitions more logically
Reorder definitions in file: first check_refname_format() and helper
functions, then the functions for managing the ref_entry and ref_array
data structures, then ref_cache, then the more "business-logicky"
stuff.  No code is changed.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-04-10 15:51:47 -07:00
Michael Haggerty
cf6672edb1 refs: remove the extra_refs API
The extra_refs provided a kludgy way to create fake references at a
global level in the hope that they would only affect some particular
code path.  The last user of this API been rewritten, so strip this
stuff out before somebody else gets the bad idea of using it.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-12 19:50:39 -08:00
Michael Haggerty
30249ee68f add_packed_ref(): new function in the refs API.
Add a new function add_packed_ref() that adds a reference directly to
the in-memory packed reference cache.  This will be useful for
creating local references while cloning.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-01-17 11:55:04 -08:00
Michael Haggerty
e6ed3ca651 ref_array: keep track of whether references are sorted
Keep track of how many entries at the beginning of a ref_array are already
sorted.  In sort_ref_array(), return early if the the array is already
sorted (i.e., if no new references has been appended to the end of the
list since the last call to sort_ref_array()).

Sort ref_arrays only when needed, namely in search_ref_array() and in
do_for_each_ref().  However, never call sort_ref_array() on the
extra_refs, because extra_refs can contain multiple entries with the same
name and because sort_ref_array() not only sorts, but de-dups its
contents.

This change is currently not useful, because entries are not added to
ref_arrays after they are created.  But in a moment they will be...

Implementation note: we could store a binary "sorted" value instead of
an integer, but storing the number of sorted entries leaves the way
open for a couple of possible future optimizations:

* In sort_ref_array(), sort *only* the unsorted entries, then merge
  them with the sorted entries.  This should be faster if most of the
  entries are already sorted.

* Teach search_ref_array() to do a binary search of any sorted
  entries, and if unsuccessful do a linear search of any unsorted
  entries.  This would avoid the need to sort the list every time that
  search_ref_array() is called, and (given some intelligence about how
  often to sort) could significantly improve the speed in certain
  hypothetical usage patterns.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-01-17 11:53:21 -08:00
Junio C Hamano
8d68493f20 Merge branch 'mh/ref-api'
* mh/ref-api:
  add_ref(): take a (struct ref_entry *) parameter
  create_ref_entry(): extract function from add_ref()
  repack_without_ref(): remove temporary
  resolve_gitlink_ref_recursive(): change to work with struct ref_cache
  Pass a (ref_cache *) to the resolve_gitlink_*() helper functions
  resolve_gitlink_ref(): improve docstring
  get_ref_dir(): change signature
  refs: change signatures of get_packed_refs() and get_loose_refs()
  is_dup_ref(): extract function from sort_ref_array()
  add_ref(): add docstring
  parse_ref_line(): add docstring
  is_refname_available(): remove the "quiet" argument
  clear_ref_array(): rename from free_ref_array()
  refs: rename parameters result -> sha1
  refs: rename "refname" variables
  struct ref_entry: document name member

Conflicts:
	cache.h
	refs.c
2011-12-20 13:25:53 -08:00
Nguyễn Thái Ngọc Duy
8cad4744ee Rename resolve_ref() to resolve_ref_unsafe()
resolve_ref() may return a pointer to a shared buffer and can be
overwritten by the next resolve_ref() calls. Callers need to
pay attention, not to keep the pointer when the next call happens.

Rename with "_unsafe" suffix to warn developers (or reviewers) before
introducing new call sites.

This patch is generated using the following command

git grep -l 'resolve_ref(' -- '*.[ch]'|xargs sed -i 's/resolve_ref(/resolve_ref_unsafe(/g'

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-12-13 09:39:46 -08:00
Nguyễn Thái Ngọc Duy
96ec7b1e70 Convert resolve_ref+xstrdup to new resolve_refdup function
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-12-13 09:26:52 -08:00
Michael Haggerty
dd73ecd1bc add_ref(): take a (struct ref_entry *) parameter
Take a pointer to the ref_entry to add to the array, rather than
creating the ref_entry within the function.  This opens the way to
having multiple kinds of ref_entries.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-12-12 09:08:53 -08:00
Michael Haggerty
cddc42587c create_ref_entry(): extract function from add_ref()
Separate the creation of the ref_entry from its addition to a ref_array.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-12-12 09:08:53 -08:00
Michael Haggerty
fe9c7b78c5 repack_without_ref(): remove temporary
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-12-12 09:08:53 -08:00
Michael Haggerty
064d51dc40 resolve_gitlink_ref_recursive(): change to work with struct ref_cache
resolve_gitlink_ref() and resolve_gitlink_ref_recursive(), together,
basically duplicated the code in git_path_submodule().  So use that
function instead.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-12-12 09:08:53 -08:00
Michael Haggerty
b0626608ea Pass a (ref_cache *) to the resolve_gitlink_*() helper functions
And remove some redundant arguments from resolve_gitlink_packed_ref().

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-12-12 09:08:53 -08:00
Michael Haggerty
3b12482358 get_ref_dir(): change signature
Change get_ref_dir() to take a (struct ref_cache *) in place of the
submodule name.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-12-12 09:08:53 -08:00
Michael Haggerty
316b097ac1 refs: change signatures of get_packed_refs() and get_loose_refs()
Change get_packed_refs() and get_loose_refs() to take a (struct
ref_cache *) instead of the name of the submodule.

Change get_ref_dir() to take a submodule name (i.e., "" for the main
module) rather than a submodule pointer (i.e., NULL for the main
module) so that refs->name can be used as its argument.  (In a moment
this function will also be changed to take a (struct ref_cache *),
too.)

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-12-12 09:08:53 -08:00
Michael Haggerty
202a56a924 is_dup_ref(): extract function from sort_ref_array()
Giving the function a name makes the code easier to understand.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-12-12 09:08:53 -08:00
Michael Haggerty
6af1038bee add_ref(): add docstring
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-12-12 09:08:52 -08:00
Michael Haggerty
fbd09e41d5 parse_ref_line(): add docstring
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-12-12 09:08:52 -08:00
Michael Haggerty
19b68b1e63 is_refname_available(): remove the "quiet" argument
quiet was always set to 0, so get rid of it.  Add a function docstring
for good measure.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-12-12 09:08:52 -08:00
Michael Haggerty
7c59511ed5 clear_ref_array(): rename from free_ref_array()
Rename the function since it doesn't actually free the array object
that is passed to it.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-12-12 09:08:51 -08:00
Michael Haggerty
85be1fe34a refs: rename parameters result -> sha1
Try consistently to use the name "sha1" for parameters to which a SHA1
will be stored.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-12-12 09:08:51 -08:00
Michael Haggerty
dfefa935ae refs: rename "refname" variables
Try to consistently use the variable name "refname" when referring to
a string that names a reference.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-12-12 09:08:51 -08:00
Michael Haggerty
c49b039bdd struct ref_entry: document name member
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-12-12 09:08:51 -08:00
Junio C Hamano
b7f7c07977 Merge branch 'nd/resolve-ref'
* nd/resolve-ref:
  Copy resolve_ref() return value for longer use
  Convert many resolve_ref() calls to read_ref*() and ref_exists()

Conflicts:
	builtin/fmt-merge-msg.c
	builtin/merge.c
	refs.c
2011-12-09 13:37:14 -08:00
Junio C Hamano
eb8aa3d2c2 Merge branch 'jc/pull-signed-tag'
* jc/pull-signed-tag:
  commit-tree: teach -m/-F options to read logs from elsewhere
  commit-tree: update the command line parsing
  commit: teach --amend to carry forward extra headers
  merge: force edit and no-ff mode when merging a tag object
  commit: copy merged signed tags to headers of merge commit
  merge: record tag objects without peeling in MERGE_HEAD
  merge: make usage of commit->util more extensible
  fmt-merge-msg: Add contents of merged tag in the merge message
  fmt-merge-msg: package options into a structure
  fmt-merge-msg: avoid early returns
  refs DWIMmery: use the same rule for both "git fetch" and others
  fetch: allow "git fetch $there v1.0" to fetch a tag
  merge: notice local merging of tags and keep it unwrapped
  fetch: do not store peeled tag object names in FETCH_HEAD
  Split GPG interface into its own helper library

Conflicts:
	builtin/fmt-merge-msg.c
	builtin/merge.c
2011-12-09 13:37:09 -08:00
Junio C Hamano
09116a1c31 refs: loosen over-strict "format" check
The add_extra_ref() interface is used to add an extra-ref that is _not_
our ref for the purpose of helping auto-following of tags and reducing
object transfer from remote repository, and they are typically formatted
as a tagname followed by ^{} to make sure no valid refs match that
pattern. In other words, these entries are deliberately formatted not to
pass check-refname-format test.

A recent series however added a test unconditionally to the add_ref()
function that is called from add_extra_ref(). The check may be sensible
for other two callsites of the add_ref() interface, but definitely is
a wrong thing to do in add_extra_ref(). Disable it.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
Acked-by: Michael Haggerty <mhagger@alum.mit.edu>
2011-11-16 21:52:24 -08:00
Nguyễn Thái Ngọc Duy
c689332391 Convert many resolve_ref() calls to read_ref*() and ref_exists()
resolve_ref() may return a pointer to a static buffer, which is not
safe for long-term use because if another resolve_ref() call happens,
the buffer may be changed.  Many call sites though do not care about
this buffer. They simply check if the return value is NULL or not.

Convert all these call sites to new wrappers to reduce resolve_ref()
calls from 57 to 34. If we change resolve_ref() prototype later on
to avoid passing static buffer out, this helps reduce changes.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-11-13 12:21:06 -08:00
Junio C Hamano
dd621df9cd refs DWIMmery: use the same rule for both "git fetch" and others
"git log frotz" can DWIM to "refs/remotes/frotz/HEAD", but in the remote
access context, "git fetch frotz" to fetch what the other side happened to
have fetched from what it calls 'frotz' (which may not have any relation
to what we consider is 'frotz') the last time would not make much sense,
so the fetch rules table did not include "refs/remotes/%.*s/HEAD".

When the user really wants to, "git fetch $there remotes/frotz/HEAD" would
let her do so anyway, so this is not about safety or security; it merely
is about confusion avoidance and discouraging meaningless usage.

Specifically, it is _not_ about ambiguity avoidance. A name that would
become ambiguous if we use the same rules table for both fetch and local
rev-parse would be ambiguous locally at the remote side.

So for the same reason as we added rule to allow "git fetch $there v1.0"
instead of "git fetch $there tags/v1.0" in the previous commit, here is a
bit longer rope for the users, which incidentally simplifies our code.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-11-07 15:34:30 -08:00
Junio C Hamano
47d84b6abc fetch: allow "git fetch $there v1.0" to fetch a tag
You can already do so with "git fetch $there tags/v1.0" but if it is not
ambiguous there is no reason to force users to type more.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-11-07 15:34:30 -08:00
Junio C Hamano
0445ba2457 Merge branch 'jc/broken-ref-dwim-fix'
* jc/broken-ref-dwim-fix:
  resolve_ref(): report breakage to the caller without warning
  resolve_ref(): expose REF_ISBROKEN flag
  refs.c: move dwim_ref()/dwim_log() from sha1_name.c
2011-10-21 16:04:36 -07:00
Junio C Hamano
2f18b4642d Merge branch 'mh/ref-api'
* mh/ref-api:
  clear_ref_cache(): inline function
  write_ref_sha1(): only invalidate the loose ref cache
  clear_ref_cache(): extract two new functions
  clear_ref_cache(): rename parameter
  invalidate_ref_cache(): expose this function in the refs API
  invalidate_ref_cache(): take the submodule as parameter
  invalidate_ref_cache(): rename function from invalidate_cached_refs()
2011-10-21 16:04:36 -07:00
Junio C Hamano
e3353046ee Merge branch 'jc/maint-remove-renamed-ref'
* jc/maint-remove-renamed-ref:
  branch -m/-M: remove undocumented RENAMED-REF

Conflicts:
	refs.c
2011-10-21 16:04:34 -07:00
Junio C Hamano
5595635002 resolve_ref(): report breakage to the caller without warning
629cd3a (resolve_ref(): emit warnings for improperly-formatted references,
2011-09-15) made resolve_ref() warn against files that are found in the
directories the ref dwimmery looks at. The intent may be good, but these
messages come from a wrong level of the API hierarchy.

Instead record the breakage in "flags" whose purpose is to explain the
result of the function to the caller, who is in a much better position to
make intelligent decision based on the information.

This updates sha1_name.c::dwim_ref() to warn against such a broken
candidate only when it does not appear directly below $GIT_DIR to restore
the traditional behaviour, as we know many files directly underneath
$GIT_DIR/ are not refs.

Warning against "git show config --" with "$GIT_DIR/config does not look
like a well-formed ref" does not make sense, and we may later tweak the
dwimmery not to even consider them as candidates, but that is a longer
term topic.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-10-19 13:58:15 -07:00
Junio C Hamano
98ac34b2b1 resolve_ref(): expose REF_ISBROKEN flag
Instead of keeping this as an internal API, let the callers find
out the reason why resolve_ref() returned NULL is not because there
was no such file in $GIT_DIR but because a file was corrupt.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-10-19 13:58:15 -07:00
Junio C Hamano
e5fa45c159 resolve_gitlink_packed_ref(): fix mismerge
2c5c66b (Merge branch 'jp/get-ref-dir-unsorted', 2011-10-10) merged a
topic that forked from the mainline before a new helper function
get_packed_refs() refactored code to read packed-refs file. The merge made
the call to the helper function with an incorrect argument. The parameter
to the function has to be a path to the submodule.

Fix the mismerge.

Helped-by: Mark Levedahl <mlevedahl@gmail.com>
Helped-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-10-17 11:44:18 -07:00
Michael Haggerty
c5f29abd80 clear_ref_cache(): inline function
clear_ref_cache() was only called from one place, so inline it
there.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-10-16 21:12:22 -07:00
Michael Haggerty
8bf90dc9bd write_ref_sha1(): only invalidate the loose ref cache
Since write_ref_sha1() can only write loose refs and cannot write
symbolic refs, there is no need for it to invalidate the packed ref
cache.

Suggested by: Martin Fick <mfick@codeaurora.org>
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-10-16 21:12:04 -07:00
Michael Haggerty
760c4512e5 clear_ref_cache(): extract two new functions
Extract two new functions from clear_cached_refs():
clear_loose_ref_cache() and clear_packed_ref_cache().

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-10-16 21:11:33 -07:00
Michael Haggerty
1b7edaf94b clear_ref_cache(): rename parameter
...for consistency with the rest of this module.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-10-16 21:11:03 -07:00
Michael Haggerty
8be8bde75f invalidate_ref_cache(): expose this function in the refs API
Make invalidate_ref_cache() an official part of the refs API.  It is
currently a fact of life that code outside of refs.c mucks about with
references.  This change gives such code a way of informing the refs
module that it should no longer trust its cache.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-10-16 21:10:49 -07:00
Michael Haggerty
3870a0d1d8 invalidate_ref_cache(): take the submodule as parameter
Instead of invalidating the ref cache on an all-or-nothing basis,
invalidate the cache for a specific submodule.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-10-16 21:09:50 -07:00
Michael Haggerty
79c7ca54e1 invalidate_ref_cache(): rename function from invalidate_cached_refs()
It is the cache that is being invalidated, not the references, and the
new name makes this unambiguous.  Rename other items analogously:

* struct cached_refs -> struct ref_cache
* cached_refs (the variable) -> ref_cache
* clear_cached_refs() -> clear_ref_cache()
* create_cached_refs() -> create_ref_cache()
* get_cached_refs() -> get_ref_cache()

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-10-16 21:08:23 -07:00
Junio C Hamano
ff74f7f118 refs.c: move dwim_ref()/dwim_log() from sha1_name.c
Both dwim_ref()/dwim_log() functions are intimately related to the ref
parsing rules defined in refs.c and better fits there. Move them together
with substitute_branch_name(), a file scope static helper function.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-10-12 10:35:38 -07:00
Junio C Hamano
b0eab01a48 branch -m/-M: remove undocumented RENAMED-REF
The commit message for c976d41 (git-branch: add options and tests for
branch renaming, 2006-11-28) mentions RENAME_REF but otherwise this is not
documented anywhere, and it does not appear in any of the tests.

Worse yet, the name of the actual file is "RENAMED-REF".

This was supposed to hold the commit object name at the tip of the branch
the most recent "branch -m/-M" renamed, but that is not necessary in order
to be able to recover from a mistake. Even when "branch -M A B" overwrites
an existing branch B, what is kept in RENAMED-REF is the commit at the tip
of the original branch A, not the commit B from the now-lost branch.

Just remove this unused "feature".

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-10-12 09:52:55 -07:00
Junio C Hamano
2c5c66be6e Merge branch 'jp/get-ref-dir-unsorted'
* jp/get-ref-dir-unsorted:
  refs.c: free duplicate entries in the ref array instead of leaking them
  refs.c: abort ref search if ref array is empty
  refs.c: ensure struct whose member may be passed to realloc is initialized
  refs: Use binary search to lookup refs faster
  Don't sort ref_list too early

Conflicts:
	refs.c
2011-10-10 15:56:19 -07:00
Junio C Hamano
9bd500048d Merge branch 'mh/check-ref-format-3'
* mh/check-ref-format-3: (23 commits)
  add_ref(): verify that the refname is formatted correctly
  resolve_ref(): expand documentation
  resolve_ref(): also treat a too-long SHA1 as invalid
  resolve_ref(): emit warnings for improperly-formatted references
  resolve_ref(): verify that the input refname has the right format
  remote: avoid passing NULL to read_ref()
  remote: use xstrdup() instead of strdup()
  resolve_ref(): do not follow incorrectly-formatted symbolic refs
  resolve_ref(): extract a function get_packed_ref()
  resolve_ref(): turn buffer into a proper string as soon as possible
  resolve_ref(): only follow a symlink that contains a valid, normalized refname
  resolve_ref(): use prefixcmp()
  resolve_ref(): explicitly fail if a symlink is not readable
  Change check_refname_format() to reject unnormalized refnames
  Inline function refname_format_print()
  Make collapse_slashes() allocate memory for its result
  Do not allow ".lock" at the end of any refname component
  Refactor check_refname_format()
  Change check_ref_format() to take a flags argument
  Change bad_ref_char() to return a boolean value
  ...
2011-10-10 15:56:18 -07:00
Junio C Hamano
11fa509957 Merge branch 'mh/iterate-refs'
* mh/iterate-refs:
  refs.c: make create_cached_refs() static
  Retain caches of submodule refs
  Store the submodule name in struct cached_refs
  Allocate cached_refs objects dynamically
  Change the signature of read_packed_refs()
  Access reference caches only through new function get_cached_refs()
  Extract a function clear_cached_refs()
2011-10-10 15:56:18 -07:00
Brandon Casey
17d68a54de refs.c: free duplicate entries in the ref array instead of leaking them
Signed-off-by: Brandon Casey <casey@nrlssc.navy.mil>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-10-10 10:05:39 -07:00
Brandon Casey
687296960d refs.c: abort ref search if ref array is empty
The bsearch() implementation on IRIX 6.5 segfaults if it is passed NULL
for the base array argument even if number-of-elements is zero.  So, let's
work around it by detecting an empty array and aborting early.

This is a useful optimization in its own right anyway, since we avoid a
useless allocation and initialization of the ref_entry when the ref array
is empty.

Signed-off-by: Brandon Casey <casey@nrlssc.navy.mil>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-10-10 10:05:22 -07:00
Brandon Casey
43d20a8c50 refs.c: ensure struct whose member may be passed to realloc is initialized
The variable "refs" is allocated on the stack but is not initialized.  It
is passed to read_packed_refs(), and its struct members may eventually be
passed to add_ref() and ALLOC_GROW().  Since the structure has not been
initialized, its members may contain random non-zero values.  So let's
initialize it.

The call sequence looks something like this:

   resolve_gitlink_packed_ref(...) {

       struct cached_refs refs;
       ...
       read_packed_refs(f, &refs);
       ...
   }

   read_packed_refs(FILE*, struct cached_refs *cached_refs) {
       ...
       add_ref(name, sha1, flag, &cached_refs->packed, &last);
       ...
   }

   add_ref(..., struct ref_array *refs, struct ref_entry **) {
       ...
       ALLOC_GROW(refs->refs, refs->nr + 1, refs->alloc);
   }

Signed-off-by: Brandon Casey <casey@nrlssc.navy.mil>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-10-10 10:05:07 -07:00
Michael Haggerty
dce4bab656 add_ref(): verify that the refname is formatted correctly
In add_ref(), verify that the refname is formatted correctly before
adding it to the ref_list.  Here we have to allow refname components
that start with ".", since (for example) the remote protocol uses
synthetic reference name ".have".  So add a new REFNAME_DOT_COMPONENT
flag that can be passed to check_refname_format() to allow leading
dots.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-10-05 13:45:31 -07:00
Michael Haggerty
7cb368421f resolve_ref(): expand documentation
Record information about resolve_ref(), hard-won via reverse
engineering, in a comment for future spelunkers.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-10-05 13:45:31 -07:00
Michael Haggerty
f989fea0e0 resolve_ref(): also treat a too-long SHA1 as invalid
If the SHA1 in a reference file is not terminated by a space or
end-of-file, consider it malformed and emit a warning.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-10-05 13:45:31 -07:00
Michael Haggerty
629cd3ac6d resolve_ref(): emit warnings for improperly-formatted references
While resolving references, if a reference is found that is in an
unrecognized format, emit a warning (and then fail, as before).
Wouldn't *you* want to know?

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-10-05 13:45:31 -07:00
Michael Haggerty
8384d78886 resolve_ref(): verify that the input refname has the right format
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-10-05 13:45:31 -07:00
Michael Haggerty
313fb010da resolve_ref(): do not follow incorrectly-formatted symbolic refs
Emit a warning and fail if a symbolic reference refers to an
incorrectly-formatted refname.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-10-05 13:45:31 -07:00
Michael Haggerty
c224ca7f66 resolve_ref(): extract a function get_packed_ref()
Making it a function and giving it a name makes the code clearer.  I
also have a strong suspicion that the function will find other uses in
the future.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-10-05 13:45:30 -07:00
Michael Haggerty
287750507d resolve_ref(): turn buffer into a proper string as soon as possible
Immediately strip off trailing spaces and null-terminate the string
holding the contents of the reference file; this allows the use of
string functions and avoids the need to keep separate track of the
string's length.  (get_sha1_hex() fails automatically if the string is
too short.)

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-10-05 13:45:30 -07:00
Michael Haggerty
1f58a03838 resolve_ref(): only follow a symlink that contains a valid, normalized refname
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-10-05 13:45:30 -07:00
Michael Haggerty
b54cb79597 resolve_ref(): use prefixcmp()
Terminate the link content string one step earlier, allowing
prefixcmp() to be used instead of the less clear memcmp().

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-10-05 13:45:30 -07:00
Michael Haggerty
7bb2bf8e5c resolve_ref(): explicitly fail if a symlink is not readable
Previously the failure came later, after a few steps in which the
length was treated like the actual length of a string.  Even though
the old code gave the same answers, it was somewhat misleading.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-10-05 13:45:30 -07:00
Michael Haggerty
a40e6fb67a Change check_refname_format() to reject unnormalized refnames
Since much of the infrastructure does not work correctly with
unnormalized refnames, change check_refname_format() to reject them.

Similarly, change "git check-ref-format" to reject unnormalized
refnames by default.  But add an option --normalize, which causes "git
check-ref-format" to normalize the refname before checking its format,
and print the normalized refname.  This is exactly the behavior of the
old --print option, which is retained but deprecated.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-10-05 13:45:30 -07:00
Michael Haggerty
7e9d2fe960 Do not allow ".lock" at the end of any refname component
Allowing any refname component to end with ".lock" is looking for
trouble; for example,

    $ git br foo.lock/bar
    $ git br foo
    fatal: Unable to create '[...]/.git/refs/heads/foo.lock': File exists.

Therefore, do not allow any refname component to end with ".lock".

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-10-05 13:45:30 -07:00
Michael Haggerty
49295d4e3f Refactor check_refname_format()
Among other things, extract a function check_refname_component().

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-10-05 13:45:29 -07:00
Michael Haggerty
8d9c50105f Change check_ref_format() to take a flags argument
Change check_ref_format() to take a flags argument that indicates what
is acceptable in the reference name (analogous to "git
check-ref-format"'s "--allow-onelevel" and "--refspec-pattern").  This
is more convenient for callers and also fixes a failure in the test
suite (and likely elsewhere in the code) by enabling "onelevel" and
"refspec-pattern" to be allowed independently of each other.

Also rename check_ref_format() to check_refname_format() to make it
obvious that it deals with refnames rather than references themselves.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-10-05 13:45:29 -07:00
Michael Haggerty
9224b73be0 Change bad_ref_char() to return a boolean value
Previously most bad characters were indicated by returning 1, but "*"
was special-cased to return 2 instead of 1.  One caller examined the
return value to see whether the special case occurred.

But it is easier (to document and understand) for bad_ref_char()
simply to return a boolean value, treating "*" like any other bad
character.  Special-case the handling of "*" (which only occurs in
very specific circumstances) at the caller.  The resulting calling
code thereby also becomes more transparent.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-10-05 13:45:29 -07:00
Julian Phillips
e9c4c11165 refs: Use binary search to lookup refs faster
Currently we linearly search through lists of refs when we need to
find a specific ref.  This can be very slow if we need to lookup a
large number of refs.  By changing to a binary search we can make this
faster.

In order to be able to use a binary search we need to change from
using linked lists to arrays, which we can manage using ALLOC_GROW.

We can now also use the standard library qsort function to sort the
refs arrays.

Signed-off-by: Julian Phillips <julian@quantumfyre.co.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-09-30 12:28:34 -07:00
Julian Phillips
b4f223c636 Don't sort ref_list too early
get_ref_dir is called recursively for subdirectories, which means that
we were calling sort_ref_list for each directory of refs instead of
once for all the refs.  This is a massive wast of processing, so now
just call sort_ref_list on the result of the top-level get_ref_dir, so
that the sort is only done once.

In the common case of only a few different directories of refs the
difference isn't very noticable, but it becomes very noticeable when
you have a large number of direcotries containing refs (e.g. as
created by Gerrit).

Reported by Martin Fick.

Signed-off-by: Julian Phillips <julian@quantumfyre.co.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-09-26 18:30:38 -07:00
Junio C Hamano
3ab24efeef refs.c: make create_cached_refs() static
There is nobody outside that calls into this helper function.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-09-11 15:59:26 -07:00
Junio C Hamano
4b1108eec7 Merge branch 'mh/check-ref-format-print-normalize'
* mh/check-ref-format-print-normalize:
  Forbid DEL characters in reference names
  check-ref-format --print: Normalize refnames that start with slashes
2011-09-06 11:42:52 -07:00
Junio C Hamano
2730f55527 Merge branch 'nd/maint-clone-gitdir'
* nd/maint-clone-gitdir:
  clone: allow to clone from .git file
  read_gitfile_gently(): rename misnamed function to read_gitfile()
2011-08-28 21:20:28 -07:00
Michael Haggerty
f3738c1ce9 Forbid DEL characters in reference names
DEL is an ASCII control character and therefore should not be
permitted in reference names.  Add tests for this and other unusual
characters.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-27 11:47:49 -07:00
Junio C Hamano
13d6ec9133 read_gitfile_gently(): rename misnamed function to read_gitfile()
The function was not gentle at all to the callers and died without giving
them a chance to deal with possible errors. Rename it to read_gitfile(),
and update all the callers.

As no existing caller needs a true "gently" variant, we do not bother
adding one at this point.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-22 14:04:56 -07:00
Junio C Hamano
6ed547b53b Merge branch 'js/ref-namespaces'
* js/ref-namespaces:
  ref namespaces: tests
  ref namespaces: documentation
  ref namespaces: Support remote repositories via upload-pack and receive-pack
  ref namespaces: infrastructure
  Fix prefix handling in ref iteration functions
2011-08-17 17:35:38 -07:00
Michael Haggerty
0e88c130f2 Retain caches of submodule refs
Instead of keeping track of one cache for refs in the main repo and
another single cache shared among submodules, keep a linked list of
cached_refs objects, one for each module/submodule. Change
invalidate_cached_refs() to invalidate all caches. (Previously, it
only invalidated the cache of the main repo because the submodule
caches were not reused anyway.)

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-14 15:18:52 -07:00
Michael Haggerty
ce40979cf8 Store the submodule name in struct cached_refs
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-14 15:18:52 -07:00
Michael Haggerty
e5dbf6056f Allocate cached_refs objects dynamically
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-14 15:18:52 -07:00
Michael Haggerty
db4dd93a4a Change the signature of read_packed_refs()
Change it to return a (struct ref_list *) instead of writing into
a cached_refs structure.  (This removes the need to create a
cached_refs structure in resolve_gitlink_packed_ref(), where it
is otherwise unneeded.)

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-14 15:18:52 -07:00
Michael Haggerty
4349a66805 Access reference caches only through new function get_cached_refs()
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-14 15:18:52 -07:00
Michael Haggerty
f130b1168e Extract a function clear_cached_refs()
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-14 15:18:51 -07:00
Josh Triplett
a1bea2c1fc ref namespaces: infrastructure
Add support for dividing the refs of a single repository into multiple
namespaces, each of which can have its own branches, tags, and HEAD.
Git can expose each namespace as an independent repository to pull from
and push to, while sharing the object store, and exposing all the refs
to operations such as git-gc.

Storing multiple repositories as namespaces of a single repository
avoids storing duplicate copies of the same objects, such as when
storing multiple branches of the same source.  The alternates mechanism
provides similar support for avoiding duplicates, but alternates do not
prevent duplication between new objects added to the repositories
without ongoing maintenance, while namespaces do.

To specify a namespace, set the GIT_NAMESPACE environment variable to
the namespace.  For each ref namespace, git stores the corresponding
refs in a directory under refs/namespaces/.  For example,
GIT_NAMESPACE=foo will store refs under refs/namespaces/foo/.  You can
also specify namespaces via the --namespace option to git.

Note that namespaces which include a / will expand to a hierarchy of
namespaces; for example, GIT_NAMESPACE=foo/bar will store refs under
refs/namespaces/foo/refs/namespaces/bar/.  This makes paths in
GIT_NAMESPACE behave hierarchically, so that cloning with
GIT_NAMESPACE=foo/bar produces the same result as cloning with
GIT_NAMESPACE=foo and cloning from that repo with GIT_NAMESPACE=bar.  It
also avoids ambiguity with strange namespace paths such as
foo/refs/heads/, which could otherwise generate directory/file conflicts
within the refs directory.

Add the infrastructure for ref namespaces: handle the GIT_NAMESPACE
environment variable and --namespace option, and support iterating over
refs in a namespace.

Signed-off-by: Josh Triplett <josh@joshtriplett.org>
Signed-off-by: Jamey Sharp <jamey@minilop.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-07-06 11:19:24 -07:00
Josh Triplett
b3cfc4066d Fix prefix handling in ref iteration functions
The do_for_each_ref iteration function accepts a prefix and a trim, and
checks for the prefix on each ref before passing in that ref; it also
supports trimming off part of the ref before passing it.  However,
do_for_each_ref used trim as the length of the prefix to check, ignoring
the actual length of the prefix.  Switch to using prefixcmp, checking
the entire length of the prefix string, to properly support a trim value
different than the length of the prefix.

Several callers passed a prefix of "refs/" to filter out everything
outside of refs/, but a trim of 0 to avoid trimming off the "refs/"; the
trim of 0 meant that the filter of "refs/" no longer applied.  Change
these callers to pass an empty prefix instead, to avoid changing the
existing behavior.  Various callers count on this lack of filtering,
such as receive-pack which uses add_extra_ref to add alternates as refs
named ".have"; adding filtering would break that, causing
t5501-fetch-push-alternates.sh to fail.  That lack of filtering doesn't
currently have any other effect, since the loose ref functions can never
supply refs outside of "refs/", and packed-refs will not normally
include such refs unless manually edited.

Signed-off-by: Josh Triplett <josh@joshtriplett.org>
Signed-off-by: Jamey Sharp <jamey@minilop.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-07-06 11:12:01 -07:00
Junio C Hamano
b985f2aeca Merge branch 'jc/maint-1.7.3-checkout-describe'
* jc/maint-1.7.3-checkout-describe:
  checkout -b <name>: correctly detect existing branch
2011-06-29 17:03:12 -07:00
Dmitry Ivankov
7be8b3baba Fix typo: existant->existent
refs.c had a error message "Trying to write ref with nonexistant object".
And no tests relied on the wrong spelling.
Also typo was present in some test scripts internals, these tests still pass.

Signed-off-by: Dmitry Ivankov <divanorama@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-06-16 10:33:50 -07:00
Junio C Hamano
c17b229454 checkout -b <name>: correctly detect existing branch
When create a new branch, we fed "refs/heads/<proposed name>" as a string
to get_sha1() and expected it to fail when a branch already exists.

The right way to check if a ref exists is to check with resolve_ref().

A naïve solution that might appear attractive but does not work is to
forbid slashes in get_describe_name() but that will not work. A describe
name is is in the form of "ANYTHING-g<short sha1>", and that ANYTHING part
comes from a original tag name used in the repository the user ran the
describe command. A sick user could have a confusing hierarchical tag
whose name is "refs/heads/foobar" (stored as refs/tags/refs/heads/foobar")
to generate a describe name "refs/heads/foobar-6-g02ac983", and we should
be able to use that name to refer to the object whose name is 02ac983.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-06-05 22:17:04 -07:00
Junio C Hamano
2d984464c6 Merge branch 'hv/submodule-find-ff-merge'
* hv/submodule-find-ff-merge:
  Implement automatic fast-forward merge for submodules
  setup_revisions(): Allow walking history in a submodule
  Teach ref iteration module about submodules

Conflicts:
	submodule.c
2010-08-21 23:27:59 -07:00
Junio C Hamano
fcd91f8de2 Merge branch 'maint'
* maint:
  backmerge a few more fixes to 1.7.1.X series
  rev-parse: fix --parse-opt --keep-dashdash --stop-at-non-option
  fix git branch -m in presence of cross devices

Conflicts:
	RelNotes
	builtin/rev-parse.c
2010-07-07 11:18:26 -07:00
Heiko Voigt
9ef6aeb09f setup_revisions(): Allow walking history in a submodule
By passing the path to a submodule in opt->submodule, the function can
be used to walk history in the named submodule repository, instead of
the toplevel repository.

Signed-off-by: Heiko Voigt <hvoigt@hvoigt.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-07-07 09:48:33 -07:00
Heiko Voigt
0bad611b1e Teach ref iteration module about submodules
We will use this in a later patch to extend setup_revisions() to
load revisions directly from a submodule.

Signed-off-by: Heiko Voigt <hvoigt@hvoigt.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-07-07 09:48:21 -07:00
Pierre Habouzit
765c22588d fix git branch -m in presence of cross devices
When you have for example a bare repository stored on NFS, and that you
create new workdirs locally (using contrib's git-new-workdir), logs/refs
is a symlink to a different device. Hence when the reflogs are renamed,
all must happen below logs/refs or one gets cross device rename errors
like:

  git branch -m foo
  error: unable to move logfile logs/refs/heads/master to tmp-renamed-log: Invalid cross-device link
  fatal: Branch rename failed

The fix is hence to use logs/refs/.tmp-renamed-log as a temporary log
name, instead of just tmp-renamed-log.

Signed-off-by: Pierre Habouzit <madcoder@debian.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-07-07 09:17:00 -07:00
Junio C Hamano
8d676d85f7 Merge branch 'gv/portable'
* gv/portable:
  test-lib: use DIFF definition from GIT-BUILD-OPTIONS
  build: propagate $DIFF to scripts
  Makefile: Tru64 portability fix
  Makefile: HP-UX 10.20 portability fixes
  Makefile: HPUX11 portability fixes
  Makefile: SunOS 5.6 portability fix
  inline declaration does not work on AIX
  Allow disabling "inline"
  Some platforms lack socklen_t type
  Make NO_{INET_NTOP,INET_PTON} configured independently
  Makefile: some platforms do not have hstrerror anywhere
  git-compat-util.h: some platforms with mmap() lack MAP_FAILED definition
  test_cmp: do not use "diff -u" on platforms that lack one
  fixup: do not unconditionally disable "diff -u"
  tests: use "test_cmp", not "diff", when verifying the result
  Do not use "diff" found on PATH while building and installing
  enums: omit trailing comma for portability
  Makefile: -lpthread may still be necessary when libc has only pthread stubs
  Rewrite dynamic structure initializations to runtime assignment
  Makefile: pass CPPFLAGS through to fllow customization

Conflicts:
	Makefile
	wt-status.h
2010-06-21 06:02:44 -07:00
Thomas Rast
157aaea5ff log_ref_setup: don't return stack-allocated array
859c301 (refs: split log_ref_write logic into log_ref_setup,
2010-05-21) refactors the stack allocation of the log_file array into
the new log_ref_setup() function, but passes it back to the caller.

Since the original intent seems to have been to split the work between
log_ref_setup and log_ref_write, make it the caller's responsibility
to allocate the buffer.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
Reported-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-06-12 09:34:17 -07:00
Erick Mattos
859c30175f refs: split log_ref_write logic into log_ref_setup
Separation of the logic for testing and preparing the reflogs from
function log_ref_write to a new non static new function: log_ref_setup.

This allows to be performed from outside the first all reasonable checks
and procedures for writing reflogs.

Signed-off-by: Erick Mattos <erick.mattos@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-06-02 11:17:46 -07:00
Gary V. Vaughan
66dbfd55e3 Rewrite dynamic structure initializations to runtime assignment
Unfortunately, there are still plenty of production systems with
vendor compilers that choke unless all compound declarations can be
determined statically at compile time, for example hpux10.20 (I can
provide a comprehensive list of our supported platforms that exhibit
this problem if necessary).

This patch simply breaks apart any compound declarations with dynamic
initialisation expressions, and moves the initialisation until after
the last declaration in the same block, in all the places necessary to
have the offending compilers accept the code.

Signed-off-by: Gary V. Vaughan <gary@thewrittenword.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-05-31 16:59:26 -07:00
Michael J Gruber
b2e256b0f0 refs.c: Write reflogs for notes just like for branch heads
The notes code intends to write reflog entries, but currently they are
not written because log_ref_write() checks for the refname path
explicitly.

Add refs/notes to the list of allowed paths so that notes references are
treated just like branch heads, i.e. according to core.logAllRefUpdates
and core.bare.

Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net>
Acked-by: Johan Herland <johan@herland.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-03-29 21:18:07 -07:00
Junio C Hamano
a86ed83cce Merge branch 'tr/notes-display'
* tr/notes-display:
  git-notes(1): add a section about the meaning of history
  notes: track whether notes_trees were changed at all
  notes: add shorthand --ref to override GIT_NOTES_REF
  commit --amend: copy notes to the new commit
  rebase: support automatic notes copying
  notes: implement helpers needed for note copying during rewrite
  notes: implement 'git notes copy --stdin'
  rebase -i: invoke post-rewrite hook
  rebase: invoke post-rewrite hook
  commit --amend: invoke post-rewrite hook
  Documentation: document post-rewrite hook
  Support showing notes from more than one notes tree
  test-lib: unset GIT_NOTES_REF to stop it from influencing tests

Conflicts:
	git-am.sh
	refs.c
2010-03-24 16:26:43 -07:00
Junio C Hamano
954f7cfdac Merge branch 'jc/maint-refs-dangling'
* jc/maint-refs-dangling:
  refs: ref entry with NULL sha1 is can be a dangling symref
2010-03-24 16:25:34 -07:00
Junio C Hamano
e01de1c912 refs: ref entry with NULL sha1 is can be a dangling symref
Brandon Casey noticed that t5505 had accidentally broken its && chain,
hiding inconsistency between the code that writes the warning to the
standard output and the test that expects to see the warning on the
standard error, which was introduced by f8948e2 (remote prune: warn
dangling symrefs, 2009-02-08).

It turns out that the issue is deeper than that.  After f8948e2, a symref
that is dangling is marked with a NULL sha1, and the idea of using NULL
sha1 to mean a deleted ref was scrapped, but somehow a follow-up eafb452
(do_one_ref(): null_sha1 check is not about broken ref, 2009-07-22)
incorrectly reorganized do_one_ref(), still thinking NULL sha1 is never
used in the code.

Fix this by:

 - adopt Brandon's fix to t5505 test;

 - introduce REF_BROKEN flag to mark a ref that fails to resolve (dangling
   symref);

 - move the check for broken ref back inside the "if we are skipping
   dangling refs" code block.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-03-15 23:37:42 -07:00
René Scharfe
8ca7880356 for_each_recent_reflog_ent(): use strbuf, fix offset handling
As Vladimir reported, "git log -g refs/stash" surprisingly showed the reflog
of HEAD if the message in the reflog file was too long.  To fix this, convert
for_each_recent_reflog_ent() to use strbuf_getwholeline() instead of fgets(),
for safety and to avoid any size limits for reflog entries.

Also reverse the logic of the part of the function that only looks at file
tails.  It used to close the file if fgets() succeeded.  The following
fgets() call in the while loop was likely to fail in this case, too, so
passing an offset to for_each_recent_reflog_ent() never worked.  Change it to
error out if strbuf_getwholeline() fails instead.

Reported-by: Vladimir Panteleev <vladimir@thecybershadow.net>
Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-03-13 13:18:09 -08:00
Thomas Rast
894a9d333e Support showing notes from more than one notes tree
With this patch, you can set notes.displayRef to a glob that points at
your favourite notes refs, e.g.,

[notes]
	displayRef = refs/notes/*

Then git-log and friends will show notes from all trees.

Thanks to Junio C Hamano for lots of feedback, which greatly
influenced the design of the entire series and this commit in
particular.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
Acked-by: Johan Herland <johan@herland.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-03-12 21:55:39 -08:00
Junio C Hamano
9517e6b843 Typofixes outside documentation area
begining -> beginning
    canonicalizations -> canonicalization
    comand -> command
    dewrapping -> unwrapping
    dirtyness -> dirtiness
    DISCLAMER -> DISCLAIMER
    explicitely -> explicitly
    feeded -> fed
    impiled -> implied
    madatory -> mandatory
    mimick -> mimic
    preceeding -> preceding
    reqeuest -> request
    substition -> substitution

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-02-03 21:28:17 -08:00
Ilari Liusvaara
b09fe971de rev-parse --branches/--tags/--remotes=pattern
Since local branch, tags and remote tracking branch namespaces are
most often used, add shortcut notations for globbing those in
manner similar to --glob option.

With this, one can express the "what I have but origin doesn't?"
as:

'git log --branches --not --remotes=origin'

Original-idea-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-01-20 12:30:25 -08:00
Ilari Liusvaara
d08bae7e22 rev-parse --glob
Add --glob=<glob-pattern> option to rev-parse and everything that
accepts its options. This option matches all refs that match given
shell glob pattern (complete with some DWIM logic).

Example:

'git log --branches --not --glob=remotes/origin'

To show what you have that origin doesn't.

Signed-off-by: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-01-20 12:29:05 -08:00
Jay Soffian
3cf6134ad0 teach warn_dangling_symref to take a FILE argument
Different callers of warn_dangling_symref() may want to control whether its
output goes to stdout or stderr so let it take a FILE argument.

Signed-off-by: Jay Soffian <jaysoffian@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-11-10 01:01:47 -08:00
Miklos Vajna
1b018fd9be git branch -D: give a better error message when lockfile creation fails
Previously the old error message just told the user that it was not
possible to delete the ref from the packed-refs file. Give instructions
on how to resolve the problem.

Signed-off-by: Miklos Vajna <vmiklos@frugalware.org>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
2009-09-29 08:14:47 -07:00
Junio C Hamano
f00ecbe42b Merge branch 'cc/replace'
* cc/replace:
  t6050: check pushing something based on a replaced commit
  Documentation: add documentation for "git replace"
  Add git-replace to .gitignore
  builtin-replace: use "usage_msg_opt" to give better error messages
  parse-options: add new function "usage_msg_opt"
  builtin-replace: teach "git replace" to actually replace
  Add new "git replace" command
  environment: add global variable to disable replacement
  mktag: call "check_sha1_signature" with the replacement sha1
  replace_object: add a test case
  object: call "check_sha1_signature" with the replacement sha1
  sha1_file: add a "read_sha1_file_repl" function
  replace_object: add mechanism to replace objects found in "refs/replace/"
  refs: add a "for_each_replace_ref" function
2009-08-21 18:47:53 -07:00
Junio C Hamano
a0f4afbe87 clean: require double -f options to nuke nested git repository and work tree
When you have an embedded git work tree in your work tree (be it
an orphaned submodule, or an independent checkout of an unrelated
project), "git clean -d -f" blindly descended into it and removed
everything.  This is rarely what the user wants.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-07-29 12:22:30 -07:00
Junio C Hamano
f87dd2152a Merge branch 'maint'
* maint:
  SunOS grep does not understand -C<n> nor -e
  Fix export_marks() error handling.
  git branch: clean up detached branch handling
  git branch: avoid unnecessary object lookups
  git branch: fix performance problem
  do_one_ref(): null_sha1 check is not about broken ref

Conflicts:
	Makefile
2009-07-24 09:27:09 -07:00
Junio C Hamano
eafb45265b do_one_ref(): null_sha1 check is not about broken ref
f8948e2 (remote prune: warn dangling symrefs, 2009-02-08) introduced a
more dangerous variant of for_each_ref() family that skips the check for
dangling refs, but it also made another unrelated check optional by
mistake.

The check to see if a ref points at 0{40} is not about brokenness, but is
about a possible future plan to represent a deleted ref by writing 40 "0"
in a loose ref when there is a stale version of the same ref already in
.git/packed-refs, so that we can implement deletion of a ref without
having to rewrite the packed refs file excluding the ref being deleted.

This check has to live outside of the conditional.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-07-22 23:07:05 -07:00
Junio C Hamano
58b1ef2f0f Merge branch 'maint'
* maint:
  checkout -f: deal with a D/F conflict entry correctly
  sha1_name.c: avoid unnecessary strbuf_release
  refs.c: release file descriptor on error return
2009-07-18 16:57:47 -07:00
Brandon Casey
9d33f7c22f refs.c: release file descriptor on error return
Signed-off-by: Brandon Casey <drafnel@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-07-16 15:07:24 -07:00
Thomas Rast
d824cbba02 Convert existing die(..., strerror(errno)) to die_errno()
Change calls to die(..., strerror(errno)) to use the new die_errno().

In the process, also make slight style adjustments: at least state
_something_ about the function that failed (instead of just printing
the pathname), and put paths in single quotes.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-06-27 11:14:53 -07:00
Christian Couder
292687003a refs: add a "for_each_replace_ref" function
This is some preparation work for the following patches that are using
the "refs/replace/" ref namespace.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-05-31 17:02:59 -07:00
Junio C Hamano
23807fa008 Merge branch 'maint'
* maint:
  Prepare for 1.6.3.2
  fix cat-file usage message and documentation
  fetch: report ref storage DF errors more accurately
  lock_ref: inform callers of unavailable ref
  merge-options.txt: Clarify merge --squash

Conflicts:
	RelNotes
2009-05-25 19:44:52 -07:00
Junio C Hamano
2c5942dbae Merge branch 'ar/unlink-err' into maint
* ar/unlink-err:
  print unlink(2) errno in copy_or_link_directory
  replace direct calls to unlink(2) with unlink_or_warn
  Introduce an unlink(2) wrapper which gives warning if unlink failed
2009-05-25 19:01:50 -07:00
Jeff King
f475e08edb lock_ref: inform callers of unavailable ref
One of the ways that locking might fail is that there is a
DF conflict between two refs (e.g., you want to lock
"foo/bar" but "foo" already exists). In this case, we return
an error, but there is no way for the caller to know the
specific problem.

This patch sets errno to ENOTDIR, which is the most sensible
code. It's what we would see if the refs were stored purely
in the filesystem (but these days we must check the
namespace manually due to packed refs).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-05-25 12:06:54 -07:00
Junio C Hamano
44ee247f8d Merge branch 'fc/decorate-tag'
* fc/decorate-tag:
  Prettify log decorations even more
  Change prettify_ref to prettify_refname
2009-05-23 01:43:50 -07:00
Junio C Hamano
e05aae684d Merge branch 'rr/forbid-bs-in-ref'
* rr/forbid-bs-in-ref:
  Disallow '\' in ref names
2009-05-23 01:39:45 -07:00
Felipe Contreras
4577e48364 Change prettify_ref to prettify_refname
In preparation to be used when the ref object is not available

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
Acked-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-05-13 20:55:48 -07:00
Robin Rosenberg
a4c2e69936 Disallow '\' in ref names
This is asking for trouble since '\' is a directory separator in
Windows and thus may produce unpredictable results.

Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-05-09 01:35:49 -07:00
Alex Riesen
691f1a28bf replace direct calls to unlink(2) with unlink_or_warn
This helps to notice when something's going wrong, especially on
systems which lock open files.

I used the following criteria when selecting the code for replacement:
- it was already printing a warning for the unlink failures
- it is in a function which already printing something or is
  called from such a function
- it is in a static function, returning void and the function is only
  called from a builtin main function (cmd_)
- it is in a function which handles emergency exit (signal handlers)
- it is in a function which is obvously cleaning up the lockfiles

Signed-off-by: Alex Riesen <raa.lkml@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-04-29 18:37:41 -07:00
Bert Wesarg
6e7b3309d3 shorten_unambiguous_ref(): add strict mode
Add the strict mode of abbreviation to shorten_unambiguous_ref(), i.e. the
resulting ref won't trigger the ambiguous ref warning.

All users of shorten_unambiguous_ref() still use the loose mode.

Signed-off-by: Bert Wesarg <bert.wesarg@googlemail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-04-13 09:36:44 -07:00
Junio C Hamano
3e52effcf6 Merge branch 'jk/show-upstream'
* jk/show-upstream:
  branch: show upstream branch when double verbose
  make get_short_ref a public function
  for-each-ref: add "upstream" format field
  for-each-ref: refactor refname handling
  for-each-ref: refactor get_short_ref function
2009-04-12 16:46:42 -07:00
Junio C Hamano
6e353a5e5d Merge branch 'cc/bisect-filter'
* cc/bisect-filter: (21 commits)
  rev-list: add "int bisect_show_flags" in "struct rev_list_info"
  rev-list: remove last static vars used in "show_commit"
  list-objects: add "void *data" parameter to show functions
  bisect--helper: string output variables together with "&&"
  rev-list: pass "int flags" as last argument of "show_bisect_vars"
  t6030: test bisecting with paths
  bisect: use "bisect--helper" and remove "filter_skipped" function
  bisect: implement "read_bisect_paths" to read paths in "$GIT_DIR/BISECT_NAMES"
  bisect--helper: implement "git bisect--helper"
  bisect: use the new generic "sha1_pos" function to lookup sha1
  rev-list: call new "filter_skip" function
  patch-ids: use the new generic "sha1_pos" function to lookup sha1
  sha1-lookup: add new "sha1_pos" function to efficiently lookup sha1
  rev-list: pass "revs" to "show_bisect_vars"
  rev-list: make "show_bisect_vars" non static
  rev-list: move code to show bisect vars into its own function
  rev-list: move bisect related code into its own file
  rev-list: make "bisect_list" variable local to "cmd_rev_list"
  refs: add "for_each_ref_in" function to refactor "for_each_*_ref" functions
  quote: add "sq_dequote_to_argv" to put unwrapped args in an argv array
  ...
2009-04-12 16:46:40 -07:00
Jeff King
7c2b3029df make get_short_ref a public function
Often we want to shorten a full ref name to something "prettier"
to show a user. For example, "refs/heads/master" is often shown
simply as "master", or "refs/remotes/origin/master" is shown as
"origin/master".

Many places in the code use a very simple formula: skip common
prefixes like refs/heads, refs/remotes, etc. This is codified in
the prettify_ref function.

for-each-ref has a more correct (but more expensive) approach:
consider the ref lookup rules, and try shortening as much as
possible while remaining unambiguous.

This patch makes the latter strategy globally available as
shorten_unambiguous_ref.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-04-07 23:22:15 -07:00
Junio C Hamano
fbdc05661d Merge branch 'jc/name-branch'
* jc/name-branch:
  Don't permit ref/branch names to end with ".lock"
  check_ref_format(): tighten refname rules
  strbuf_check_branch_ref(): a helper to check a refname for a branch
  Fix branch -m @{-1} newname
  check-ref-format --branch: give Porcelain a way to grok branch shorthand
  strbuf_branchname(): a wrapper for branch name shorthands
  Rename interpret/substitute nth_last_branch functions

Conflicts:
	Documentation/git-check-ref-format.txt
2009-04-06 00:43:44 -07:00
Junio C Hamano
5aaa507b06 Merge branch 'cc/sha1-bsearch' into HEAD
* cc/sha1-bsearch: (95 commits)
  patch-ids: use the new generic "sha1_pos" function to lookup sha1
  sha1-lookup: add new "sha1_pos" function to efficiently lookup sha1
  Update draft release notes to 1.6.3
  GIT 1.6.2.2
  send-email: ensure quoted addresses are rfc2047 encoded
  send-email: correct two tests which were going interactive
  Documentation: git-svn: fix trunk/fetch svn-remote key typo
  Mailmap: Allow empty email addresses to be mapped
  Cleanup warning about known issues in cvsimport documentation
  Documentation: Remove an odd "instead"
  send-email: ask_default should apply to all emails, not just the first
  send-email: don't attempt to prompt if tty is closed
  fix portability problem with IS_RUN_COMMAND_ERR
  Documentation: use "spurious .sp" XSLT if DOCBOOK_SUPPRESS_SP is set
  mailmap: resurrect lower-casing of email addresses
  builtin-clone.c: no need to strdup for setenv
  builtin-clone.c: make junk_pid static
  git-svn: add a double quiet option to hide git commits
  Update draft release notes to 1.6.2.2
  Documentation: push.default applies to all remotes
  ...
2009-04-04 23:04:50 -07:00
Christian Couder
2a8177b63d refs: add "for_each_ref_in" function to refactor "for_each_*_ref" functions
The "for_each_{tag,branch,remote,replace,}_ref" functions are
redefined in terms of "for_each_ref_in" so that we can lose the
hardcoded length of prefix strings from the code.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
2009-03-30 01:22:53 -07:00
Junio C Hamano
f23336f5c1 Merge branch 'db/push-cleanup'
* db/push-cleanup:
  Move push matching and reporting logic into transport.c
  Use a common function to get the pretty name of refs

Conflicts:
	transport.c
2009-03-26 00:28:46 -07:00
Shawn O. Pearce
3e262b95c5 Don't permit ref/branch names to end with ".lock"
We already skip over loose refs under $GIT_DIR/refs if the name
ends with ".lock", so creating a branch named "foo.lock" will not
appear in the output of "git branch", "git for-each-ref", nor will
its commit be considered reachable by "git rev-list --all".

In the latter case this is especially evil, as it may cause
repository corruption when objects reachable only through such a
ref are deleted by "git prune".

It should be reasonably safe to deny use of ".lock" as a ref suffix.
In prior versions of Git such branches would be "phantom branches";
you can create it, but you can't see it in "git branch" output.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-03-24 17:02:20 -07:00
Junio C Hamano
cbdffe4093 check_ref_format(): tighten refname rules
This changes the rules for refnames to forbid:

 (1) a refname that contains "@{" in it.

     Some people and foreign SCM converter may have named their branches
     as frotz@24 and we still want to keep supporting it.

     However, "git branch frotz@{24}" is a disaster.  It cannot even
     checked out because "git checkout frotz@{24}" will interpret it as
     "detach the HEAD at twenty-fourth reflog entry of the frotz branch".

 (2) a refname that ends with a dot.

     We already reject a path component that begins with a dot, primarily
     to avoid ambiguous range interpretation.  If we allowed ".B" as a
     valid ref, it is unclear if "A...B" means "in dot-B but not in A" or
     "either in A or B but not in both".

     But for this to be complete, we need also to forbid "A." to avoid "in
     B but not in A-dot".  This was not a problem in the original range
     notation, but we should have added this restriction when three-dot
     notation was introduced.

     Unlike "no dot at the beginning of any path component" rule, this
     rule does not have to be "no dot at the end of any path component",
     because you cannot abbreviate the tail end away, similar to you can
     say "dot-B" to mean "refs/heads/dot-B".

For these reasons, it is not likely people created branches with these
names on purpose, but we have allowed such names to be used for quite some
time, and it is possible that people created such branches by mistake or
by accident.

To help people with branches with such unfortunate names to recover,
we still allow "branch -d 'bad.'" to delete such branches, and also allow
"branch -m bad. good" to rename them.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-03-24 00:53:03 -07:00
Miklos Vajna
edbc25c5b3 refs: use warning() instead of fprintf(stderr, "warning: ")
Signed-off-by: Miklos Vajna <vmiklos@frugalware.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-03-23 21:02:28 -07:00
Daniel Barkalow
a9c37a72c4 Use a common function to get the pretty name of refs
The result should be consistent between fetch and push, so we ought to
use the same code in both cases, even though it's short.

Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-03-09 15:41:16 -07:00
Junio C Hamano
5ad6b0252b Adjust js/remote-improvements and db/refspec-wildcard-in-the-middle
The latter topic changes the definition of how refspec's src and dst side
is stored in-core; it used to be that the asterisk for pattern was
omitted, but now it is included.  The former topic handcrafts an old style
refspec to feed the refspec matching machinery that lacks the asterisk and
triggers an error.

This resolves the semantic clash between the two topics early before they
need to be merged to integration branches.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-03-08 00:24:21 -08:00
Daniel Barkalow
abd2bde78b Support '*' in the middle of a refspec
In order to keep the requirements strict, each * has to be a full path
component, and there may only be one * per side. This requirement is
enforced entirely by check_ref_format(); the matching implementation
will substitute the whatever matches the * in the lhs for the * in the
rhs.

Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-03-07 12:19:28 -08:00
Daniel Barkalow
08fbdb3043 Keep '*' in pattern refspecs
In order to do anything more capable with refspecs, the first step is
to keep the entire input. Additionally, validate patterns by checking
for the ref matching the rules for a pattern as given by
check_ref_format(). This requires a slight change to
check_ref_format() to make it enforce the requirement that the '*'
immediately follow a '/'.

Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-03-07 12:19:24 -08:00
Jeff King
5483f79998 refactor find_ref_by_name() to accept const list
Since it doesn't actually touch its argument, this makes
sense.

However, we still want to return a non-const version (which
requires a cast) so that this:

  struct ref *a, *b;
  a = find_ref_by_name(b);

works. Unfortunately, you can also silently strip the const
from a variable:

  struct ref *a;
  const struct ref *b;
  a = find_ref_by_name(b);

This is a classic C const problem because there is no way to
say "return the type with the same constness that was passed
to us"; we provide the same semantics as standard library
functions like strchr.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Jay Soffian <jaysoffian@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-02-26 00:49:44 -08:00
Junio C Hamano
f8948e2fbc remote prune: warn dangling symrefs
If you prune from the remote "frotz" that deleted the ref your tracking
branch remotes/frotz/HEAD points at, the symbolic ref will become
dangling.  We used to detect this as an error condition and issued a
message every time refs are enumerated.

This stops the error message, but moves the warning to "remote prune".

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-02-10 22:26:20 -08:00
Junio C Hamano
101d15e097 Introduce for_each_recent_reflog_ent().
This can be used to scan only the last few kilobytes of a reflog, as a
cheap optimization when the data you are looking for is likely to be
found near the end of it.  The caller is expected to fall back to the
full scan if that is not the case.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-01-19 22:18:29 -08:00
Junio C Hamano
8bb4646dae Merge branch 'maint'
* maint:
  Fix non-literal format in printf-style calls
  git-submodule: Avoid printing a spurious message.
  git ls-remote: make usage string match manpage
  Makefile: help people who run 'make check' by mistake
2008-11-11 14:49:50 -08:00
Daniel Lowe
9db56f71b9 Fix non-literal format in printf-style calls
These were found using gcc 4.3.2-1ubuntu11 with the warning:

    warning: format not a string literal and no format arguments

Incorporated suggestions from Brandon Casey <casey@nrlssc.navy.mil>.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-11-11 14:43:59 -08:00
Junio C Hamano
bc9c0248a5 Merge branch 'maint'
* maint:
  GIT 1.6.0.4
  Update RPM spec for the new location of git-cvsserver.
  push: fix local refs update if already up-to-date
  do not force write of packed refs

Conflicts:
	builtin-revert.c
2008-11-08 21:33:55 -08:00
Junio C Hamano
832e719d79 Merge branch 'cb/maint-update-ref-fix' into maint
* cb/maint-update-ref-fix:
  push: fix local refs update if already up-to-date
  do not force write of packed refs
2008-11-08 17:32:49 -08:00
Junio C Hamano
8b1981d32b Merge branch 'ar/maint-mksnpath' into maint
* ar/maint-mksnpath:
  Use git_pathdup instead of xstrdup(git_path(...))
  git_pathdup: returns xstrdup-ed copy of the formatted path
  Fix potentially dangerous use of git_path in ref.c
  Add git_snpath: a .git path formatting routine with output buffer
  Fix potentially dangerous uses of mkpath and git_path
  Fix mkpath abuse in dwim_ref and dwim_log of sha1_name.c
  Add mksnpath which allows you to specify the output buffer

Conflicts:
	builtin-revert.c
	rerere.c
2008-11-08 16:13:19 -08:00
Junio C Hamano
3b8572a429 Merge branch 'mv/maint-branch-m-symref' into maint
* mv/maint-branch-m-symref:
  update-ref --no-deref -d: handle the case when the pointed ref is packed
  git branch -m: forbid renaming of a symref
  Fix git update-ref --no-deref -d.
  rename_ref(): handle the case when the reflog of a ref does not exist
  Fix git branch -m for symrefs.
2008-11-08 16:07:37 -08:00
Clemens Buchacher
5bdd8d4a30 do not force write of packed refs
We force writing a ref if it does not exist. Originally, we only had to look
for the ref file to check if it existed. Now we have to look for a packed ref
as well. Luckily, resolve_ref already does all the work for us.

Signed-off-by: Clemens Buchacher <drizzd@aon.at>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-11-05 14:09:43 -08:00
Junio C Hamano
a1a846a19e Merge branch 'ar/mksnpath'
* ar/mksnpath:
  Use git_pathdup instead of xstrdup(git_path(...))
  git_pathdup: returns xstrdup-ed copy of the formatted path
  Fix potentially dangerous use of git_path in ref.c
  Add git_snpath: a .git path formatting routine with output buffer
  Fix potentially dangerous uses of mkpath and git_path
  Fix potentially dangerous uses of mkpath and git_path
  Fix mkpath abuse in dwim_ref and dwim_log of sha1_name.c
  Add mksnpath which allows you to specify the output buffer

Conflicts:
	builtin-revert.c
2008-11-05 11:35:53 -08:00
Junio C Hamano
efcce2e1f0 Merge branch 'mv/maint-branch-m-symref'
* mv/maint-branch-m-symref:
  update-ref --no-deref -d: handle the case when the pointed ref is packed
  git branch -m: forbid renaming of a symref
  Fix git update-ref --no-deref -d.
  rename_ref(): handle the case when the reflog of a ref does not exist
  Fix git branch -m for symrefs.
2008-11-05 11:33:19 -08:00
Miklos Vajna
045a476f91 update-ref --no-deref -d: handle the case when the pointed ref is packed
In this case we did nothing in the past, but we should delete the
reference in fact.

The problem was that when the symref is not packed but the referenced
ref is packed, then we assumed that the symref is packed as well, but
symrefs are never packed.

Signed-off-by: Miklos Vajna <vmiklos@frugalware.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-10-31 22:41:55 -07:00
Junio C Hamano
98b35e2c74 Merge branch 'ar/maint-mksnpath' into ar/mksnpath
* ar/maint-mksnpath:
  Use git_pathdup instead of xstrdup(git_path(...))
  git_pathdup: returns xstrdup-ed copy of the formatted path
  Fix potentially dangerous use of git_path in ref.c
  Add git_snpath: a .git path formatting routine with output buffer

Conflicts:
	builtin-revert.c
	refs.c
	rerere.c
2008-10-30 18:08:58 -07:00
Alex Riesen
a4f34cbb4c Use git_pathdup instead of xstrdup(git_path(...))
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-10-30 17:52:24 -07:00
Alex Riesen
958a4789e0 Fix potentially dangerous use of git_path in ref.c
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-10-30 17:18:29 -07:00
Miklos Vajna
fa58186c9b git branch -m: forbid renaming of a symref
There may be cases where one would really want to rename the symbolic
ref without changing its value, but "git branch -m" is not such a
use-case.

Signed-off-by: Miklos Vajna <vmiklos@frugalware.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-10-30 13:50:48 -07:00
Miklos Vajna
450d4c0f5a rename_ref(): handle the case when the reflog of a ref does not exist
We tried to check if a reflog of a ref is a symlink without first
checking if it exists, which is a bug.

Signed-off-by: Miklos Vajna <vmiklos@frugalware.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-10-26 14:43:26 -07:00
Miklos Vajna
eca35a25a9 Fix git branch -m for symrefs.
This had two problems with symrefs. First, it copied the actual sha1
instead of the "pointer", second it failed to remove the old ref after a
successful rename.

Given that till now delete_ref() always dereferenced symrefs, a new
parameters has been introduced to delete_ref() to allow deleting refs
without a dereference.

Signed-off-by: Miklos Vajna <vmiklos@frugalware.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-10-26 14:42:57 -07:00
Junio C Hamano
a157400c97 Merge branch 'jc/maint-co-track'
* jc/maint-co-track:
  Enhance hold_lock_file_for_{update,append}() API
  demonstrate breakage of detached checkout with symbolic link HEAD
  Fix "checkout --track -b newbranch" on detached HEAD

Conflicts:
	builtin-commit.c
2008-10-21 17:58:11 -07:00
Junio C Hamano
acd3b9eca8 Enhance hold_lock_file_for_{update,append}() API
This changes the "die_on_error" boolean parameter to a mere "flags", and
changes the existing callers of hold_lock_file_for_update/append()
functions to pass LOCK_DIE_ON_ERROR.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-10-19 12:35:37 -07:00
Christian Couder
4886b89f8f refs: improve comments about "reading" argument of "resolve_ref"
The existing in-code comment was misleading.  An access that is not
"reading" may often be "writing", but it does not have to be.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-09-09 08:34:00 -07:00
Junio C Hamano
bb293b831b Merge branch 'maint'
* maint:
  Start preparing release notes for 1.5.6.3
  git-submodule - Fix bugs in adding an existing repo as a module
  bash: offer only paths after '--'
  Remove unnecessary pack-*.keep file after successful git-clone
  make deleting a missing ref more quiet
2008-07-09 00:19:50 -07:00
Jeff King
d1a4489a56 avoid null SHA1 in oldest reflog
When the user specifies a ref by a reflog entry older than
one we have (e.g., "HEAD@{20 years ago"}), we issue a
warning and give them the "from" value of the oldest reflog
entry. That is, we say "we don't know what happened before
this entry, but before this we know we had some particular
SHA1".

However, the oldest reflog entry is often a creation event
such as clone or branch creation. In this case, the entry
claims that the ref went from "00000..." (the null sha1) to
the new value, and the reflog lookup returns the null sha1.

While this is technically correct (the entry tells us that
the ref didn't exist at the specified time) it is not
terribly useful to the end user. What they probably want
instead is "the oldest useful sha1 that this ref ever had".
This patch changes the behavior such that if the oldest ref
would return the null sha1, it instead returns the first
value the ref ever had.

We never discovered this problem in the test scripts because
we created "fake" reflogs that had only a specified segment
of history. This patch updates the tests with a creation
event at the beginning of history.

Signed-off-by: Jeff King <peff@peff.net>
Acked-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-07-08 13:57:27 -07:00
Jeff King
0b294c0abf make deleting a missing ref more quiet
If git attempts to delete a ref, but the unlink of the ref
file fails, we print a message to stderr. This is usually a
good thing, but if the error is ENOENT, then it indicates
that the ref has _already_ been deleted. And since that's
our goal, it doesn't make sense to complain to the user.

This harmonizes the error reporting behavior for the
unpacked and packed cases; the packed case already printed
nothing on ENOENT, but the unpacked printed unconditionally.

Additionally, send-pack would, when deleting the tracking
ref corresponding to a remote delete, print "Failed to
delete" on any failure. This can be a misleading
message, since we actually _did_ delete at the remote side,
but we failed to delete locally. Rather than make the
message more precise, let's just eliminate it entirely; the
delete_ref routine already takes care of printing out a much
more specific message about what went wrong.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-07-08 13:05:11 -07:00
Junio C Hamano
b84c343c88 Merge branch 'db/clone-in-c'
* db/clone-in-c:
  Add test for cloning with "--reference" repo being a subset of source repo
  Add a test for another combination of --reference
  Test that --reference actually suppresses fetching referenced objects
  clone: fall back to copying if hardlinking fails
  builtin-clone.c: Need to closedir() in copy_or_link_directory()
  builtin-clone: fix initial checkout
  Build in clone
  Provide API access to init_db()
  Add a function to set a non-default work tree
  Allow for having for_each_ref() list extra refs
  Have a constant extern refspec for "--tags"
  Add a library function to add an alternate to the alternates file
  Add a lockfile function to append to a file
  Mark the list of refs to fetch as const

Conflicts:

	cache.h
	t/t5700-clone-reference.sh
2008-05-25 13:41:37 -07:00
Junio C Hamano
e2e2defc14 Merge branch 'lh/git-file'
* lh/git-file:
  Teach GIT-VERSION-GEN about the .git file
  Teach git-submodule.sh about the .git file
  Teach resolve_gitlink_ref() about the .git file
  Add platform-independent .git "symlink"
2008-05-05 19:16:16 -07:00
Daniel Barkalow
e142a3c61d Allow for having for_each_ref() list extra refs
These refs can be anything, but they are most likely useful as
pointing to objects that you know are in the object database but don't
have any regular refs for. For example, when cloning with --reference,
the refs in this repository should be listed as objects that we have,
even though we don't have refs in our newly-created repository for
them yet.

Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-05-04 17:41:44 -07:00
Heikki Orsila
0104ca09e3 Make read_in_full() and write_in_full() consistent with xread() and xwrite()
xread() and xwrite() return ssize_t values as their native POSIX
counterparts read(2) and write(2).

To be consistent, read_in_full() and write_in_full() should also return
ssize_t values.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-04-29 23:11:57 -07:00
Lars Hjemli
842abf06f3 Teach resolve_gitlink_ref() about the .git file
When .git in a submodule is a file, resolve_gitlink_ref() needs to pick up
the real GIT_DIR of the submodule from that file.

Signed-off-by: Lars Hjemli <hjemli@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-04-09 01:22:50 -07:00
Junio C Hamano
f830d45b9f Merge commit '74359821' into js/reflog-delete
* commit '74359821': (128 commits)
  tests: introduce test_must_fail
  Fix builtin checkout crashing when given an invalid path
  templates/Makefile: don't depend on local umask setting
  Correct name of diff_flush() in API documentation
  Start preparing for 1.5.4.4
  format-patch: remove a leftover debugging message
  completion: support format-patch's --cover-letter option
  Eliminate confusing "won't bisect on seeked tree" failure
  builtin-reflog.c: don't install new reflog on write failure
  send-email: fix In-Reply-To regression
  git-svn: Don't prompt for client cert password everytime.
  git.el: Do not display empty directories.
  Fix 'git cvsexportcommit -w $cvsdir ...' when used with relative $GIT_DIR
  Add testcase for 'git cvsexportcommit -w $cvsdir ...' with relative $GIT_DIR
  Prompt to continue when editing during rebase --interactive
  Documentation/git svn log: add a note about timezones.
  git-p4: Support usage of perforce client spec
  git-p4: git-p4 submit cleanups.
  git-p4: Removed git-p4 submit --direct.
  git-p4: Clean up git-p4 submit's log message handling.
  ...
2008-03-03 01:20:19 -08:00
Shawn O. Pearce
0ae91be0e1 Optimize peel_ref for the current ref of a for_each_ref callback
Currently the only caller of peel_ref is show-ref, which is using
this function to show the peeled tag information if it is available
from an existing packed-refs file.  The call happens during the
for_each_ref callback function, so we have the proper struct ref_list
already on the call stack but it is not easily available to return
the peeled information to the caller.

We now save the current struct ref_list item before calling back
into the callback function so that future calls to peel_ref from
within the callback function can quickly access the current ref.
Doing so will save us an lstat() per ref processed as we no longer
have to check the filesystem to see if the ref exists as a loose
file or is packed.  This current ref caching also saves a linear
scan of the cached packed refs list.

As a micro-optimization we test the address of the passed ref name
against the current_ref->name before we go into the much more costly
strcmp().  Nearly any caller of peel_ref will be passing us the same
string do_for_each_ref passed them, which is current_ref->name.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-02-24 10:01:24 -08:00
Shawn O. Pearce
8c87dc77ae Protect peel_ref fallback case from NULL parse_object result
If the SHA-1 we are requesting the object for does not exist in
the object database we get a NULL back.  Accessing the type from
that is not likely to succeed on any system.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-02-24 00:52:55 -08:00
Brandon Casey
435fc8523f refs.c: make close_ref() and commit_ref() non-static
This is in preparation to the reflog-expire changes which will
allow updating the ref after expiring the reflog.

Signed-off-by: Brandon Casey <casey@nrlssc.navy.mil>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-02-22 22:57:38 -08:00
Brandon Casey
b531394d58 refs.c: rework ref_locks by abstracting from underlying struct lock_file
Instead of calling close_lock_file() and commit_lock_file() directly,
which take a struct lock_file argument, add two new functions:
close_ref() and commit_ref(), which handle calling the previous
lock_file functions and modifying the ref_lock structure.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-01-16 15:36:10 -08:00
Brandon Casey
4ed7cd3ab0 Improve use of lockfile API
Remove remaining double close(2)'s.  i.e. close() before
commit_locked_index() or commit_lock_file().

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-01-16 15:35:35 -08:00
Linus Torvalds
c3b0dec509 Be more careful about updating refs
This makes write_ref_sha1() more careful: it actually checks the SHA1 of
the ref it is updating, and refuses to update a ref with an object that it
cannot find.

Perhaps more importantly, it also refuses to update a branch head with a
non-commit object. I don't quite know *how* the stable series maintainers
were able to corrupt their repository to have a HEAD that pointed to a tag
rather than a commit object, but they did. Which results in a totally
broken repository that cannot be cloned or committed on.

So make it harder for people to shoot themselves in the foot like that.

The test t1400-update-ref.sh is fixed at the same time, as it
assumed that the commands involved in the particular test would
not care about corrupted repositories whose refs point at
nonexistant bogus objects.  That assumption does not hold true
anymore.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-01-16 11:53:35 -08:00
Junio C Hamano
257f3020f6 Update callers of check_ref_format()
This updates send-pack and fast-import to use symbolic constants
for checking the return values from check_ref_format(), and also
futureproof the logic in lock_any_ref_for_update() to explicitly
name the case that is usually considered an error but is Ok for
this particular use.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-01-02 11:20:09 -08:00
Junio C Hamano
5f7b202a7f lock_any_ref_for_update(): reject wildcard return from check_ref_format
Recent check_ref_format() returns -3 as well as -1 (general
error) and -2 (less than two levels).  The caller was explicitly
checking for -1, to allow "HEAD" but still needed to disallow
bogus refs.

This introduces symbolic constants for the return values from
check_ref_format() to make them read better and more
meaningful.  Normal ref creation codepath can still treat
non-zero return values as errors.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-01-02 02:28:54 -08:00
Junio C Hamano
774751a8bc Re-fix "builtin-commit: fix --signoff"
An earlier fix to the said commit was incomplete; it mixed up the
meaning of the flag parameter passed to the internal fmt_ident()
function, so this corrects it.

git_author_info() and git_committer_info() can be told to issue a
warning when no usable user information is found, and optionally can be
told to error out.  Operations that actually use the information to
record a new commit or a tag will still error out, but the caller to
leave reflog record will just silently use bogus user information.

Not warning on misconfigured user information while writing a reflog
entry is somewhat debatable, but it is probably nicer to the users to
silently let it pass, because the only information you are losing is who
checked out the branch.

 * git_author_info() and git_committer_info() used to take 1 (positive
   int) to error out with a warning on misconfiguration; this is now
   signalled with a symbolic constant IDENT_ERROR_ON_NO_NAME.

 * These functions used to take -1 (negative int) to warn but continue;
   this is now signalled with a symbolic constant IDENT_WARN_ON_NO_NAME.

 * fmt_ident() function implements the above error reporting behaviour
   common to git_author_info() and git_committer_info().  A symbolic
   constant IDENT_NO_DATE can be or'ed in to the flag parameter to make
   it return only the "Name <email@address.xz>".

 * fmt_name() is a thin wrapper around fmt_ident() that always passes
   IDENT_ERROR_ON_NO_NAME and IDENT_NO_DATE.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-12-09 00:55:55 -08:00
Junio C Hamano
9bbe6db85f Merge branch 'sp/refspec-match'
* sp/refspec-match:
  refactor fetch's ref matching to use refname_match()
  push: use same rules as git-rev-parse to resolve refspecs
  add refname_match()
  push: support pushing HEAD to real branch name
2007-12-04 17:07:10 -08:00
Junio C Hamano
fd200790dc Merge branch 'jk/send-pack'
* jk/send-pack: (24 commits)
  send-pack: cluster ref status reporting
  send-pack: fix "everything up-to-date" message
  send-pack: tighten remote error reporting
  make "find_ref_by_name" a public function
  Fix warning about bitfield in struct ref
  send-pack: assign remote errors to each ref
  send-pack: check ref->status before updating tracking refs
  send-pack: track errors for each ref
  git-push: add documentation for the newly added --mirror mode
  Add tests for git push'es mirror mode
  Update the tracking references only if they were succesfully updated on remote
  Add a test checking if send-pack updated local tracking branches correctly
  git-push: plumb in --mirror mode
  Teach send-pack a mirror mode
  send-pack: segfault fix on forced push
  Reteach builtin-ls-remote to understand remotes
  send-pack: require --verbose to show update of tracking refs
  receive-pack: don't mention successful updates
  more terse push output
  Build in ls-remote
  ...
2007-11-24 16:45:37 -08:00
Steffen Prohaska
605b4978a1 refactor fetch's ref matching to use refname_match()
The old rules used by fetch were coded as a series of ifs.  The old
rules are:
1) match full refname if it starts with "refs/" or matches "HEAD"
2) verify that full refname starts with "refs/"
3) match abbreviated name in "refs/" if it starts with "heads/",
    "tags/", or "remotes/".
4) match abbreviated name in "refs/heads/"

This is replaced by the new rules
a) match full refname
b) match abbreviated name prefixed with "refs/"
c) match abbreviated name prefixed with "refs/heads/"

The details of the new rules are different from the old rules.  We no
longer verify that the full refname starts with "refs/".  The new rule
(a) matches any full string.  The old rules (1) and (2) were stricter.
Now, the caller is responsible for using sensible full refnames.  This
should be the case for the current code.  The new rule (b) is less
strict than old rule (3).  The new rule accepts abbreviated names that
start with a non-standard prefix below "refs/".

Despite this modifications the new rules should handle all cases as
expected.  Two tests are added to verify that fetch does not resolve
short tags or HEAD in remotes.

We may even think about loosening the rules a bit more and unify them
with the rev-parse rules.  This would be done by replacing
ref_ref_fetch_rules with ref_ref_parse_rules.  Note, the two new test
would break.

Signed-off-by: Steffen Prohaska <prohaska@zib.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-11-18 18:39:01 -08:00
Steffen Prohaska
79803322c1 add refname_match()
We use at least two rulesets for matching abbreviated refnames with
full refnames (starting with 'refs/').  git-rev-parse and git-fetch
use slightly different rules.

This commit introduces a new function refname_match
(const char *abbrev_name, const char *full_name, const char **rules).

abbrev_name is expanded using the rules and matched against full_name.
If a match is found the function returns true.  rules is a NULL-terminate
list of format patterns with "%.*s", for example:

    const char *ref_rev_parse_rules[] = {
               "%.*s",
               "refs/%.*s",
               "refs/tags/%.*s",
               "refs/heads/%.*s",
               "refs/remotes/%.*s",
               "refs/remotes/%.*s/HEAD",
               NULL
    };

Asterisks are included in the format strings because this is the form
required in sha1_name.c.  Sharing the list with the functions there is
a good idea to avoid duplicating the rules.  Hopefully this
facilitates unified matching rules in the future.

This commit makes the rules used by rev-parse for resolving refs to
sha1s available for string comparison.  Before this change, the rules
were buried in get_sha1*() and dwim_ref().

A follow-up commit will refactor the rules used by fetch.

refname_match() will be used for matching refspecs in git-send-pack.

Thanks to Daniel Barkalow <barkalow@iabervon.org> for pointing
out that ref_matches_abbrev in remote.c solves a similar problem
and care should be taken to avoid confusion.

Signed-off-by: Steffen Prohaska <prohaska@zib.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-11-18 18:39:00 -08:00
Jeff King
cda69f481d make "find_ref_by_name" a public function
This was a static in remote.c, but is generally useful.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-11-18 02:34:34 -08:00
Johannes Sixt
549799b4a1 refs.c: Remove unused get_ref_sha1()
Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-11-15 21:16:51 -08:00
Shawn O. Pearce
2e13e5d892 Merge branch 'master' into db/fetch-pack
There's a number of tricky conflicts between master and
this topic right now due to the rewrite of builtin-push.
Junio must have handled these via rerere; I'd rather not
deal with them again so I'm pre-merging master into the
topic.  Besides this topic somehow started to depend on
the strbuf series that was in next, but is now in master.
It no longer compiles on its own without the strbuf API.

* master: (184 commits)
  Whip post 1.5.3.4 maintenance series into shape.
  Minor usage update in setgitperms.perl
  manual: use 'URL' instead of 'url'.
  manual: add some markup.
  manual: Fix example finding commits referencing given content.
  Fix wording in push definition.
  Fix some typos, punctuation, missing words, minor markup.
  manual: Fix or remove em dashes.
  Add a --dry-run option to git-push.
  Add a --dry-run option to git-send-pack.
  Fix in-place editing functions in convert.c
  instaweb: support for Ruby's WEBrick server
  instaweb: allow for use of auto-generated scripts
  Add 'git-p4 commit' as an alias for 'git-p4 submit'
  hg-to-git speedup through selectable repack intervals
  git-svn: respect Subversion's [auth] section configuration values
  gtksourceview2 support for gitview
  fix contrib/hooks/post-receive-email hooks.recipients error message
  Support cvs via git-shell
  rebase -i: use diff plumbing instead of porcelain
  ...

Conflicts:

	Makefile
	builtin-push.c
	rsh.c
2007-10-16 00:15:25 -04:00
Johannes Schindelin
7155b727c9 Introduce remove_dir_recursively()
There was a function called remove_empty_dir_recursive() buried
in refs.c.  Expose a slightly enhanced version in dir.h: it can now
optionally remove a non-empty directory.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-09-30 00:04:39 -07:00
Pierre Habouzit
182af8343c Use xmemdupz() in many places.
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-09-18 17:42:17 -07:00
Carlos Rica
3d9f037c60 Function for updating refs.
A function intended to be called from builtins updating refs
by locking them before write, specially those that came from
scripts using "git update-ref".

[jc: with minor fixups]

Signed-off-by: Carlos Rica <jasampler@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-09-05 11:29:33 -07:00
Alex Riesen
cbbb218f8b Fix filehandle leak in "git branch -D"
On Windows (it can't touch open files in any way) the following fails:

    git branch -D branch1 branch2

if the both branches are in packed-refs.

Signed-off-by: Alex Riesen <raa.lkml@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-08-10 22:50:06 -07:00
Junio C Hamano
0ec29a4760 log_ref_write() -- do not chomp reflog message at the first LF
A reflog file is organized as one-line-per-entry records, and we
enforced the file format integrity by chomping the given message
at the first LF.  This changes it to convert them to SP, which
is more in line with the --pretty=oneline format.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-07-29 23:28:55 -07:00
Junio C Hamano
73013afd14 Make show_rfc2822_date() just another date output format.
These days, show_date() takes a date_mode parameter to specify
the output format, and a separate specialized function for dates
in E-mails does not make much sense anymore.

This retires show_rfc2822_date() function and make it just
another date output format.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-07-13 23:14:52 -07:00
Jim Meyering
91c8d5905c detect close failure on just-written file handles
I audited git for potential undetected write failures.
In the cases fixed below, the diagnostics I add mimic the diagnostics
used in surrounding code, even when that means not reporting
the precise strerror(errno) cause of the error.

Signed-off-by: Jim Meyering <jim@meyering.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-06-26 21:48:53 -07:00
Junio C Hamano
4175e9e3a8 More static
There still are quite a few symbols that ought to be static.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-06-13 02:02:10 -07:00
Daniel Barkalow
8558fd9ece Move refspec pattern matching to match_refs().
This means that send-pack and http-push will support pattern refspecs,
so builtin-push.c doesn't have to expand them, and also git push can
just turn --tags into "refs/tags/*", further simplifying
builtin-push.c

check_ref_format() gets a third "conditionally okay" result for
something that's valid as a pattern but not as a particular ref.

Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-05-26 01:20:10 -07:00
Sven Verdoolaege
68db31cc28 git-update-ref: add --no-deref option for overwriting/detaching ref
git-checkout is also adapted to make use of this new option
instead of the handcrafted command sequence.

Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-05-10 15:24:44 -07:00
Junio C Hamano
afb5b6a24b Merge branch 'lt/gitlink'
* lt/gitlink:
  Tests for core subproject support
  Expose subprojects as special files to "git diff" machinery
  Fix some "git ls-files -o" fallout from gitlinks
  Teach "git-read-tree -u" to check out submodules as a directory
  Teach git list-objects logic to not follow gitlinks
  Fix gitlink index entry filesystem matching
  Teach "git-read-tree -u" to check out submodules as a directory
  Teach git list-objects logic not to follow gitlinks
  Don't show gitlink directories when we want "other" files
  Teach git-update-index about gitlinks
  Teach directory traversal about subprojects
  Fix thinko in subproject entry sorting
  Teach core object handling functions about gitlinks
  Teach "fsck" not to follow subproject links
  Add "S_IFDIRLNK" file mode infrastructure for git links
  Add 'resolve_gitlink_ref()' helper function
  Avoid overflowing name buffer in deep directory structures
  diff-lib: use ce_mode_from_stat() rather than messing with modes manually
2007-04-21 17:21:10 -07:00
Julian Phillips
c774aab98c refs.c: add a function to sort a ref list, rather then sorting on add
Rather than sorting the refs list while building it, sort in one
go after it is built using a merge sort.  This has a large
performance boost with large numbers of refs.

It shouldn't happen that we read duplicate entries into the same
list, but just in case sort_ref_list drops them if the SHA1s are
the same, or dies, as we have no way of knowing which one is the
correct one.

Signed-off-by: Julian Phillips <julian@quantumfyre.co.uk>
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-04-18 16:20:57 -07:00
Carlos Rica
1401f46bb4 Use const qualifier for 'sha1' parameter in delete_ref function
delete_ref function does not change the 'sha1' parameter. Non-const pointer
causes a compiler warning if you call to the function using a const argument.

Signed-off-by: Carlos Rica <jasampler@gmail.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-04-17 22:00:18 -07:00
Linus Torvalds
0ebde32c87 Add 'resolve_gitlink_ref()' helper function
This new function resolves a ref in *another* git repository.  It's
named for its intended use: to look up the git link to a subproject.

It's not actually wired up to anything yet, but we're getting closer to
having fundamental plumbing support for "links" from one git directory
to another, which is the basis of subproject support.

[jc: amended a FILE* leak]

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-04-10 13:44:16 -07:00
Lars Hjemli
19eba1515a Make builtin-branch.c handle the git config file
This moves the knowledge about .git/config usage out of refs.c and into
builtin-branch.c instead, which allows git-branch to update HEAD to point
at the moved branch before attempting to update the config file. It also
allows git-branch to exit with an error code if updating the config file
should fail.

Signed-off-by: Lars Hjemli <hjemli@gmail.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-04-06 16:54:39 -07:00
Lars Hjemli
d26f9fef47 rename_ref(): only print a warning when config-file update fails
If git_config_rename_section() fails, rename_ref() used to return 1, which
left HEAD pointing to an absent refs/heads file (since the actual renaming
had already occurred).

Signed-off-by: Lars Hjemli <hjemli@gmail.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-04-06 16:54:37 -07:00
Nicolas Pitre
605fac8b5b update HEAD reflog when branch pointed to by HEAD is directly modified
The HEAD reflog is updated as well as the reflog for the branch pointed
to by HEAD whenever it is referenced with "HEAD".

There are some cases where a specific branch may be modified directly.
In those cases, the HEAD reflog should be updated as well if it is a
symref to that branch in order to be consistent.

Signed-off-by: Nicolas Pitre <nico@cam.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-22 03:02:48 -07:00
Junio C Hamano
ed287ab7fa Merge branch 'maint'
* maint:
  git.el: Retrieve commit log information from .dotest directory.
  git.el: Avoid appending a signoff line that is already present.
  setup_git_directory_gently: fix off-by-one error
  user-manual: install user manual stylesheet with other web documents
  user-manual: fix rendering of history diagrams
  user-manual: fix missing colon in git-show example
  user-manual: fix inconsistent use of pull and merge
  user-manual: fix inconsistent example
  glossary: fix overoptimistic automatic linking of defined terms
  Documentation: s/seperator/separator/
  Adjust reflog filemode in shared repository
2007-03-10 22:07:26 -08:00
Matthias Kestenholz
443b92b6e5 Adjust reflog filemode in shared repository
Without this, committing in a group-shared repository would not work
even though all developers are in the same group.

Signed-off-by: Matthias Kestenholz <matthias@spinlock.ch>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-09 16:46:53 -08:00
Shawn O. Pearce
dc49cd769b Cast 64 bit off_t to 32 bit size_t
Some systems have sizeof(off_t) == 8 while sizeof(size_t) == 4.
This implies that we are able to access and work on files whose
maximum length is around 2^63-1 bytes, but we can only malloc or
mmap somewhat less than 2^32-1 bytes of memory.

On such a system an implicit conversion of off_t to size_t can cause
the size_t to wrap, resulting in unexpected and exciting behavior.
Right now we are working around all gcc warnings generated by the
-Wshorten-64-to-32 option by passing the off_t through xsize_t().

In the future we should make xsize_t on such problematic platforms
detect the wrapping and die if such a file is accessed.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-07 11:15:26 -08:00
Junio C Hamano
253e772ede Merge branch 'maint'
* maint:
  Unset NO_C99_FORMAT on Cygwin.
  Fix a "pointer type missmatch" warning.
  Fix some "comparison is always true/false" warnings.
  Fix an "implicit function definition" warning.
  Fix a "label defined but unreferenced" warning.
  Document the config variable format.suffix
  git-merge: fail correctly when we cannot fast forward.
  builtin-archive: use RUN_SETUP
  Fix git-gc usage note
2007-03-03 19:47:46 -08:00
Ramsay Jones
ee96d11beb Fix a "label defined but unreferenced" warning.
Signed-off-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-03 18:43:25 -08:00
Junio C Hamano
cc44c7655f Mechanical conversion to use prefixcmp()
This mechanically converts strncmp() to use prefixcmp(), but only when
the parameters match specific patterns, so that they can be verified
easily.  Leftover from this will be fixed in a separate step, including
idiotic conversions like

    if (!strncmp("foo", arg, 3))

  =>

    if (!(-prefixcmp(arg, "foo")))

This was done by using this script in px.perl

   #!/usr/bin/perl -i.bak -p
   if (/strncmp\(([^,]+), "([^\\"]*)", (\d+)\)/ && (length($2) == $3)) {
           s|strncmp\(([^,]+), "([^\\"]*)", (\d+)\)|prefixcmp($1, "$2")|;
   }
   if (/strncmp\("([^\\"]*)", ([^,]+), (\d+)\)/ && (length($1) == $3)) {
           s|strncmp\("([^\\"]*)", ([^,]+), (\d+)\)|(-prefixcmp($2, "$1"))|;
   }

and running:

   $ git grep -l strncmp -- '*.c' | xargs perl px.perl

Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-02-20 22:03:15 -08:00
Junio C Hamano
acb39f64c6 for-each-reflog: not having $GIT_DIR/logs directory is not an error.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-02-12 23:22:07 -08:00
Johannes Schindelin
b4dd485696 for_each_reflog_ent: be forgiving about missing message
Some reflogs are/were generated without a message; do not plainly
ignore those entries.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-02-08 16:06:10 -08:00
Junio C Hamano
d48744d1a8 create_symref(): create leading directories as needed.
Otherwise "git remote add -t master -m master" without the
initial fetch would not work.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-02-07 23:41:43 -08:00
Junio C Hamano
fcee5a145d for-each-reflog: fix case for empty log directory
When we remove the last reflog in a directory, opendir() would
succeed and we would iterate over its dirents, expecting retval
to be initialized to zero and setting it to non-zero only upon
seeing an error.  If the directory is empty, oops!, we do not
have anybody that touches retval.

The problem is because we initialize retval to errno even on
success from opendir(), which would leave the errno unmolested.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-02-07 09:18:57 -08:00
Junio C Hamano
d77ee72662 Merge branch 'master' into np/dreflog
This is to resolve conflicts early in preparation for possible
inclusion of "reflog on detached HEAD" series by Nico, as having
it in 1.5.0 would really help us remove confusion between
detached and attached states.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-02-03 23:05:34 -08:00
Nicolas Pitre
eb8381c885 scan reflogs independently from refs
Currently, the search for all reflogs depends on the existence of
corresponding refs under the .git/refs/ directory.  Let's scan the
.git/logs/ directory directly instead.

Signed-off-by: Nicolas Pitre <nico@cam.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-02-03 11:57:18 -08:00
Junio C Hamano
a2f9fe92eb lock_any_ref_for_update(): do not accept malformatted refs.
We used to use lock_any_ref_for_update() because the command
needs to also update HEAD (which is not under refs/, so
lock_ref_sha1() cannot be used).  The function however did not
check for refs with illegal characters in them.

Use check_ref_format() to catch malformed refs.  For this check,
we specifically do not want to say having less than two levels
in the name is illegal to allow HEAD (and perhaps other special
refs in the future).

Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-29 00:57:07 -08:00
Junio C Hamano
47fc52e287 create_symref(): do not assume pathname from git_path() persists long enough
Being lazy to rely on the cycling N buffers mkpath() and friends
return is nice in general, but it makes it too easy to introduce
new bugs that are "mysterious".

Introduction of read_ref() in create_symref() after calling
git_path() to get the git_HEAD value (i.e. the path to create a
new symref at) consumed more than the available buffers and
broke a later call to mkpath() that derives lockpath from it.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-28 02:16:46 -08:00
Nicolas Pitre
8b5157e407 add logref support to git-symbolic-ref
Signed-off-by: Nicolas Pitre <nico@cam.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-28 02:16:46 -08:00
Nicolas Pitre
41b625b047 move create_symref() past log_ref_write()
This doesn't change the code at all.  It is done to make the next patch
more obvious.

Signed-off-by: Nicolas Pitre <nico@cam.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-28 02:16:46 -08:00
Nicolas Pitre
bd104db164 enable separate reflog for HEAD
If HEAD is tied to a branch then both logs/HEAD and logs/heads/<branch> are
updated.  This is also true for any symbolic refs in general, but only HEAD
will see its reflog created automatically.

Signed-off-by: Nicolas Pitre <nico@cam.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-28 02:16:46 -08:00
Nicolas Pitre
1655707c9e lock_ref_sha1_basic(): remember the original name of a ref when resolving it
A ref might be pointing to another ref but only the name of the last ref
is remembered.  Let's remember about the first name as well.

Signed-off-by: Nicolas Pitre <nico@cam.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-28 02:16:46 -08:00
Nicolas Pitre
9a13f0b71b make reflog filename independent from struct ref_lock
This allows for ref_log_write() to be used in a more flexible way,
and is needed for future changes.

This is only code reorg with no behavior change.

Signed-off-by: Nicolas Pitre <nico@cam.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-28 02:16:46 -08:00
Junio C Hamano
8a56da2962 create_symref: check error return from open().
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-26 17:00:57 -08:00
Junio C Hamano
8ac65937d0 Make sure we do not write bogus reflog entries.
The file format dictates that entries are LF terminated so
the message cannot have one in it.  Chomp the message to make
sure it only has a single line if necessary, while removing the
leading whitespace.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-26 02:26:04 -08:00
Junio C Hamano
cb280e1075 Allow non-developer to clone, checkout and fetch more easily.
The code that uses committer_info() in reflog can barf and die
whenever it is asked to update a ref.  And I do not think
calling ignore_missing_committer_name() upfront like recent
receive-pack did in the aplication is a reasonable workaround.

What the patch does.

 - git_committer_info() takes one parameter.  It used to be "if
   this is true, then die() if the name is not available due to
   bad GECOS, otherwise issue a warning once but leave the name
   empty".  The reason was because we wanted to prevent bad
   commits from being made by git-commit-tree (and its
   callers).  The value 0 is only used by "git var -l".

   Now it takes -1, 0 or 1.  When set to -1, it does not
   complain but uses the pw->pw_name when name is not
   available.  Existing 0 and 1 values mean the same thing as
   they used to mean before.  0 means issue warnings and leave
   it empty, 1 means barf and die.

 - ignore_missing_committer_name() and its existing caller
   (receive-pack, to set the reflog) have been removed.

 - git-format-patch, to come up with the phoney message ID when
   asked to thread, now passes -1 to git_committer_info().  This
   codepath uses only the e-mail part, ignoring the name.  It
   used to barf and die.  The other call in the same program
   when asked to add signed-off-by line based on committer
   identity still passes 1 to make sure it barfs instead of
   adding a bogus s-o-b line.

 - log_ref_write in refs.c, to come up with the name to record
   who initiated the ref update in the reflog, passes -1.  It
   used to barf and die.

The last change means that git-update-ref, git-branch, and
commit walker backends can now be used in a repository with
reflog by somebody who does not have the user identity required
to make a commit.  They all used to barf and die.

I've run tests and all of them seem to pass, and also tried "git
clone" as a user whose GECOS is empty -- git clone works again
now (it was broken when reflog was enabled by default).

But this definitely needs extra sets of eyeballs.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-25 21:16:58 -08:00
Junio C Hamano
76a44c5c0b show-branch --reflog: show the reflog message at the top.
This changes the output so the list at the top shows the reflog
message, along with their relative timestamps.

You can use --reflog=<n> to show <n> most recent log entries, or
use --reflog=<n>,<b> to show <n> entries going back from the
entry <b>.  <b> can be either a number (so --reflog=4,20 shows 4
records starting from @{20}) or a timestamp (e.g. --reflog='4,1 day').

Here is a sample output (with --list option):

  $ git show-branch --reflog=10 --list jc/show-reflog
    [jc/show-reflog@{0}] (3 minutes ago) commit (amend): show-branch --ref
    [jc/show-reflog@{1}] (5 minutes ago) reset HEAD^
    [jc/show-reflog@{2}] (14 minutes ago) commit: show-branch --reflog: sho
    [jc/show-reflog@{3}] (14 minutes ago) commit: show-branch --reflog: sho
    [jc/show-reflog@{4}] (18 minutes ago) commit (amend): Extend read_ref_a
    [jc/show-reflog@{5}] (18 minutes ago) commit (amend): Extend read_ref_a
    [jc/show-reflog@{6}] (18 minutes ago) commit (amend): Extend read_ref_a
    [jc/show-reflog@{7}] (18 minutes ago) am: read_ref_at(): allow retrievi
    [jc/show-reflog@{8}] (18 minutes ago) reset --hard HEAD~4
    [jc/show-reflog@{9}] (61 minutes ago) commit: show-branch --reflog: use

This shows what I did more cleanly:

  $ git show-branch --reflog=10 jc/show-reflog
  ! [jc/show-reflog@{0}] (3 minutes ago) commit (amend): show-branch --ref
   ! [jc/show-reflog@{1}] (5 minutes ago) reset HEAD^
    ! [jc/show-reflog@{2}] (14 minutes ago) commit: show-branch --reflog:
     ! [jc/show-reflog@{3}] (14 minutes ago) commit: show-branch --reflog:
      ! [jc/show-reflog@{4}] (18 minutes ago) commit (amend): Extend read_
       ! [jc/show-reflog@{5}] (18 minutes ago) commit (amend): Extend read
        ! [jc/show-reflog@{6}] (18 minutes ago) commit (amend): Extend rea
         ! [jc/show-reflog@{7}] (18 minutes ago) am: read_ref_at(): allow
          ! [jc/show-reflog@{8}] (18 minutes ago) reset --hard HEAD~4
           ! [jc/show-reflog@{9}] (61 minutes ago) commit: show-branch --r
  ----------
  +          [jc/show-reflog@{0}] show-branch --reflog: show the reflog
    +        [jc/show-reflog@{2}] show-branch --reflog: show the reflog
   +++       [jc/show-reflog@{1}] show-branch --reflog: show the reflog
  +++++      [jc/show-reflog@{4}] Extend read_ref_at() to be usable fro
       +     [jc/show-reflog@{5}] Extend read_ref_at() to be usable fro
        +    [jc/show-reflog@{6}] Extend read_ref_at() to be usable fro
         +   [jc/show-reflog@{7}] read_ref_at(): allow retrieving the r
           + [jc/show-reflog@{9}] show-branch --reflog: use updated rea
           + [jc/show-reflog@{9}^] read_ref_at(): allow reporting the c
           + [jc/show-reflog@{9}~2] show-branch --reflog: show the refl
           + [jc/show-reflog@{9}~3] read_ref_at(): allow retrieving the
  ++++++++++ [jc/show-reflog@{8}] dwim_ref(): Separate name-to-ref DWIM

At @{9}, I had a commit to complete 5 patch series, but I wanted
to consolidate two commits that enhances read_ref_at() into one
(they were @{9}^ and @{9}~3), and another two that touch show-branch
into one (@{9} and @{9}~2).

I first saved them with "format-patch -4", and then did a reset
at @{8}.  At @{7}, I applied one of them with "am", and then
used "git-apply" on the other one, and amended the commit at
@{6} (so @{6} and @{7} has the same parent).  I did not like the
log message, so I amended again at @{5}.

Then I cherry-picked @{9}~2 to create @{3} (the log message
shows that it needs to learn to set GIT_REFLOG_ACTION -- it uses
"git-commit" and the log entry is attributed for it).  Another
cherry-pick built @{2} out of @{9}, but what I wanted to do was
to squash these two into one, so I did a "reset HEAD^" at @{1}
and then made the final commit by amending what was at the top.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-19 17:57:53 -08:00
Junio C Hamano
16d7cc90dd Extend read_ref_at() to be usable from places other than sha1_name.
You can pass an extra argument to the function to receive the
reflog message information.  Also when the log does not go back
beyond the point the user asked, the cut-off time and count are
given back to the caller for emitting the error messages as
appropriately.

We could later add configuration for get_sha1_basic() to make it
an error instead of it being just a warning.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-19 17:57:53 -08:00
Junio C Hamano
cb48cb585f refs.c::read_ref_at(): fix bogus munmap() call.
The code uses mmap() to read reflog data, but moves the pointer around
while reading, and uses that updated pointer in the call to munmap().

Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-19 00:41:37 -08:00
Junio C Hamano
2266bf27b3 for_each_reflog_ent: do not leak FILE *
The callback function can signal an early return by returning non-zero,
but the function leaked the FILE * opened on the reflog when doing so.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-18 23:25:54 -08:00
Jason Riedy
d9e74d5745 Solaris 5.8 returns ENOTDIR for inappropriate renames.
The reflog code clears empty directories when rename returns
either EISDIR or ENOTDIR.  Seems to be the only place.

Signed-off-by: Jason Riedy <ejr@cs.berkeley.edu>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-15 22:27:05 -08:00
Junio C Hamano
e861ce1692 Merge branch 'jc/bare'
* jc/bare:
  Disallow working directory commands in a bare repository.
  git-fetch: allow updating the current branch in a bare repository.
  Introduce is_bare_repository() and core.bare configuration variable
  Move initialization of log_all_ref_updates
2007-01-11 16:50:36 -08:00
Johannes Schindelin
883d60fa97 Sanitize for_each_reflog_ent()
It used to ignore the return value of the helper function; now, it
expects it to return 0, and stops iteration upon non-zero return
values; this value is then passed on as the return value of
for_each_reflog_ent().

Further, it makes no sense to force the parsing upon the helper
functions; for_each_reflog_ent() now calls the helper function with
old and new sha1, the email, the timestamp & timezone, and the message.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-09 03:04:04 -08:00
Andy Whitcroft
93822c2239 short i/o: fix calls to write to use xwrite or write_in_full
We have a number of badly checked write() calls.  Often we are
expecting write() to write exactly the size we requested or fail,
this fails to handle interrupts or short writes.  Switch to using
the new write_in_full().  Otherwise we at a minimum need to check
for EINTR and EAGAIN, where this is appropriate use xwrite().

Note, the changes to config handling are much larger and handled
in the next patch in the sequence.

Signed-off-by: Andy Whitcroft <apw@shadowen.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-08 15:44:47 -08:00
Andy Whitcroft
93d26e4cb9 short i/o: fix calls to read to use xread or read_in_full
We have a number of badly checked read() calls.  Often we are
expecting read() to read exactly the size we requested or fail, this
fails to handle interrupts or short reads.  Add a read_in_full()
providing those semantics.  Otherwise we at a minimum need to check
for EINTR and EAGAIN, where this is appropriate use xread().

Signed-off-by: Andy Whitcroft <apw@shadowen.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-08 15:44:47 -08:00
Junio C Hamano
7d1864ce67 Introduce is_bare_repository() and core.bare configuration variable
This removes the old is_bare_git_dir(const char *) to ask if a
directory, if it is a GIT_DIR, is a bare repository, and
replaces it with is_bare_repository(void *).  The function looks
at core.bare configuration variable if exists but uses the old
heuristics: if it is ".git" or ends with "/.git", then it does
not look like a bare repository, otherwise it does.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-07 21:36:35 -08:00
Junio C Hamano
510c5a8ee3 Move initialization of log_all_ref_updates
The patches to prevent Porcelainish that require working tree
from doing any damage in a bare repository make a lot of sense,
and I want to make the is_bare_git_dir() function more reliable.

In order to allow the repository owner override the heuristic
implemented in is_bare_git_dir() if/when it misidentifies a
particular repository, it would make sense to introduce a new
configuration variable "[core] bare = true/false", and make
is_bare_git_dir() notice it.

The scripts would do a 'repo-config --bool --get core.bare' and
iff the command fails (i.e. there is no such variable in the
configuration file), it would use the heuristic implemented at
the script level [*1*].

However, setup_git_env() which is called a lot earlier than we
even read from the repository configuration currently makes a
call to is_bare_git_dir(), in order to change the default
setting for log_all_ref_updates.  It somehow feels that this is
a hack.

By the way, [*1*] is another thing I hate about the current
config mechanism.  "git-repo-config --get" does not know what
the possible configuration variables are, let alone what the
default values for them are.  It allows us not to maintain a
centralized configuration table, which makes it easy to
introduce ad-hoc variables and gives a warm fuzzy feeling of
being modular, but my feeling is that it is turning out to be a
rather high price to pay for scripts.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-07 21:36:35 -08:00
Junio C Hamano
cf2999eb4c Merge branch 'sp/mmap'
* sp/mmap: (27 commits)
  Spell default packedgitlimit slightly differently
  Increase packedGit{Limit,WindowSize} on 64 bit systems.
  Update packedGit config option documentation.
  mmap: set FD_CLOEXEC for file descriptors we keep open for mmap()
  pack-objects: fix use of use_pack().
  Fix random segfaults in pack-objects.
  Cleanup read_cache_from error handling.
  Replace mmap with xmmap, better handling MAP_FAILED.
  Release pack windows before reporting out of memory.
  Default core.packdGitWindowSize to 1 MiB if NO_MMAP.
  Test suite for sliding window mmap implementation.
  Create pack_report() as a debugging aid.
  Support unmapping windows on 'temporary' packfiles.
  Improve error message when packfile mmap fails.
  Ensure core.packedGitWindowSize cannot be less than 2 pages.
  Load core configuration in git-verify-pack.
  Fully activate the sliding window pack access.
  Unmap individual windows rather than entire files.
  Document why header parsing won't exceed a window.
  Loop over pack_windows when inflating/accessing data.
  ...

Conflicts:

	cache.h
	pack-check.c
2007-01-07 00:12:47 -08:00
Junio C Hamano
e27e609bbf Merge branch 'maint'
* maint:
  pack-check.c::verify_packfile(): don't run SHA-1 update on huge data
  Fix infinite loop when deleting multiple packed refs.
2007-01-04 22:28:21 -08:00
Junio C Hamano
1084b845d9 Fix infinite loop when deleting multiple packed refs.
It was stupid to link the same element twice to lock_file_list
and end up in a loop, so we certainly need a fix.

But it is not like we are taking a lock on multiple files in
this case.  It is just that we leave the linked element on the
list even after commit_lock_file() successfully removes the
cruft.

We cannot remove the list element in commit_lock_file(); if we
are interrupted in the middle of list manipulation, the call to
remove_lock_file_on_signal() will happen with a broken list
structure pointed by lock_file_list, which would cause the cruft
to remain, so not removing the list element is the right thing
to do.  Instead we should be reusing the element already on the
list.

There is already a code for that in lock_file() function in
lockfile.c.  The code checks lk->next and the element is linked
only when it is not already on the list -- which is incorrect
for the last element on the list (which has NULL in its next
field), but if you read the check as "is this element already on
the list?" it actually makes sense.  We do not want to link it
on the list again, nor we would want to set up signal/atexit
over and over.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-03 01:22:35 -08:00
Shawn O. Pearce
c4712e4553 Replace mmap with xmmap, better handling MAP_FAILED.
In some cases we did not even bother to check the return value of
mmap() and just assume it worked.  This is bad, because if we are
out of virtual address space the kernel returned MAP_FAILED and we
would attempt to dereference that address, segfaulting without any
real error output to the user.

We are replacing all calls to mmap() with xmmap() and moving all
MAP_FAILED checking into that single location.  If a mmap call
fails we try to release enough least-recently-used pack windows
to possibly succeed, then retry the mmap() attempt.  If we cannot
mmap even after releasing pack memory then we die() as none of our
callers have any reasonable recovery strategy for a failed mmap.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-12-29 11:36:45 -08:00
Junio C Hamano
e19b9ddab3 core.logallrefupdates: log remotes/ tracking branches.
Not using reflog for tags/ was very sensible; not giving reflog
for the remotes/ was not.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-12-28 18:37:33 -08:00
Junio C Hamano
e29cb53a8b reflog: fix warning message.
When ref@{N} is specified on a ref that has only M entries (M < N),
instead of saying the initial timestamp the reflog has, warn that
there is only M entries.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-12-20 17:22:10 -08:00
Junio C Hamano
2ff81662c2 add for_each_reflog_ent() iterator
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-12-20 17:22:10 -08:00
Junio C Hamano
85023577a8 simplify inclusion of system header files.
This is a mechanical clean-up of the way *.c files include
system header files.

 (1) sources under compat/, platform sha-1 implementations, and
     xdelta code are exempt from the following rules;

 (2) the first #include must be "git-compat-util.h" or one of
     our own header file that includes it first (e.g. config.h,
     builtin.h, pkt-line.h);

 (3) system headers that are included in "git-compat-util.h"
     need not be included in individual C source files.

 (4) "git-compat-util.h" does not have to include subsystem
     specific header files (e.g. expat.h).

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-12-20 09:51:35 -08:00
Johannes Schindelin
dc81c58cd6 git-branch: rename config vars branch.<branch>.*, too
When renaming a branch, the corresponding config section should
be renamed, too.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-12-16 13:38:44 -08:00
Junio C Hamano
abcb49cb56 Merge branch 'lh/branch-rename'
* lh/branch-rename:
  git-branch: let caller specify logmsg
  rename_ref: use lstat(2) when testing for symlink
  git-branch: add options and tests for branch renaming

Conflicts:

	builtin-branch.c
2006-12-13 11:07:51 -08:00
Junio C Hamano
37adac765a send-pack: tighten checks for remote names
"git push $URL HEAD~6" created a bogus ref HEAD~6 immediately
under $GIT_DIR of the remote repository.  While we should keep
refspecs that have arbitrary extended SHA-1 expression on the
source side working (e.g. "HEAD~6:refs/tags/yesterday"), we
should not create bogus ref on the other end.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-12-13 10:30:11 -08:00
Lars Hjemli
c976d415e5 git-branch: add options and tests for branch renaming
Extend git-branch with the following options:

  git-branch -m|-M [<oldbranch>] newbranch

The -M variation is required to force renaming over an exsisting
branchname.

This also indroduces $GIT_DIR/RENAME_REF which is a "metabranch"
used when renaming branches. It will always hold the original sha1
for the latest renamed branch.

Additionally, if $GIT_DIR/logs/RENAME_REF exists, all branch rename
events are logged there.

Finally, some testcases are added to verify the new options.

Signed-off-by: Lars Hjemli <hjemli@gmail.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-12-05 23:50:57 -08:00
Lars Hjemli
678d0f4cbf git-branch: let caller specify logmsg
This changes the signature of rename_ref() in refs.[hc] to include a
logmessage for the reflogs.

Also, builtin-branch.c is modified to provide a proper logmessage + call
setup_ident() before any logmessages are written.

Signed-off-by: Lars Hjemli <hjemli@gmail.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-12-05 23:50:57 -08:00
Lars Hjemli
16c2bfbb44 rename_ref: use lstat(2) when testing for symlink
The current check for symlinked reflogs was based on stat(2), which is
utterly embarrassing.

Fix it, and add a matching testcase.

Signed-off-by: Lars Hjemli <hjemli@gmail.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-12-05 23:50:57 -08:00
Junio C Hamano
f4204ab9f6 Store peeled refs in packed-refs (take 2).
This fixes the previous implementation which failed to optimize
repositories with tons of lightweight tags.  The updated
packed-refs format begins with "# packed-refs with:" line that
lists the kind of extended data the file records.  Currently,
there is only one such extension defined, "peeled".  This stores
the "peeled tag" on a line that immediately follows a line for a
tag object itself in the format "^<sha-1>".

The header line itself and any extended data are ignored by
older implementation, so packed-refs file generated with this
version can still be used by older git.  packed-refs made by
older git can of course be used with this version.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-11-21 23:37:35 -08:00
Junio C Hamano
cf0adba788 Store peeled refs in packed-refs file.
This would speed up "show-ref -d" in a repository with mostly
packed tags.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-11-19 18:45:44 -08:00
Junio C Hamano
ef06b91804 do_for_each_ref: perform the same sanity check for leftovers.
An earlier commit b37a562a added a check to see if the ref
points at a valid object (as a part of 'negative ref' support
which we currently do not use), but did so only while iterating
over both packed and loose refs, and forgot to apply the same
check while iterating over the remaining ones.

We might want to replace the "if null then omit it" check with
"eh --- what business does a 0{40} value have here?" complaint
later since we currently do not use negative refs, but that is
a separate issue.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-11-19 18:44:29 -08:00
Junio C Hamano
2e6d8f181d Merge branch 'jc/reflog' into lj/refs
* jc/reflog:
  sha1_name.c: avoid compilation warnings.
  ref-log: allow ref@{count} syntax.
2006-10-26 18:48:30 -07:00
Junio C Hamano
3b463c3f02 ref-log: fix D/F conflict coming from deleted refs.
After deleting a branch l/k, you should be able to create a
branch l.  Earlier we added remove_empty_directories() on the
ref creation side to remove leftover .git/refs/l directory but
we also need a matching code to remove .git/logs/refs/l
directory.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-10-19 01:28:47 -07:00
Junio C Hamano
1974bf620b core.logallrefupdates thinko-fix 2006-10-09 21:15:59 -07:00
Junio C Hamano
4057deb5de core.logallrefupdates create new log file only for branch heads.
It used to mean "create log file for any ref that is updated",
but now it creates new log files only for branch heads.

The old behaviour made this configuration less useful than
otherwise it would be; automatically creating log file for tags
is almost always not useful.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-10-08 01:35:18 -07:00
Junio C Hamano
ab2a1a32ff ref-log: allow ref@{count} syntax.
Often I find myself wanting to say 'tip of "next" before I
merged the last three topics'.  Now I can say that with:

	git log next@{3}..next

Since small integers alone are invalid input strings to
approxidate, there is no fear of confusion.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-10-05 23:17:11 -07:00
Junio C Hamano
ff989b8d46 Merge branch 'master' into lj/refs
* master: (99 commits)
  lock_ref_sha1_basic does not remove empty directories on BSD
  git-push: .git/remotes/ file does not require SP after colon
  git-mv: invalidate the removed path properly in cache-tree
  Makefile: install and clean merge-recur, still.
  GIT 1.4.3-rc1
  gitweb: tree view: hash_base and hash are now context sensitive
  git-diff -B output fix.
  fetch: Reset remote refs list each time fetch_main is called
  Remove -fPIC which was only needed for Git.xs
  Fix approxidate() to understand 12:34 AM/PM are 00:34 and 12:34
  git-diff -B output fix.
  Make cvsexportcommit remove files.
  diff --stat: ensure at least one '-' for deletions, and one '+' for additions
  diff --stat=width[,name-width]: allow custom diffstat output width.
  gitweb: History: blob and tree are first, then commitdiff, etc
  gitweb: Remove redundant "commit" from history
  http/ftp: optionally ask curl to not use EPSV command
  gitweb: Don't use quotemeta on internally generated strings
  gitweb: Add snapshot to shortlog
  gitweb: Factor out gitweb_have_snapshot()
  ...
2006-10-02 11:49:59 -07:00
Dennis Stosberg
7a21632fa3 lock_ref_sha1_basic does not remove empty directories on BSD
lock_ref_sha1_basic relies on errno beeing set to EISDIR by the
call to read() in resolve_ref() to detect directories.  But calling
read() on a directory under NetBSD returns EPERM, and even succeeds
for local filesystems on FreeBSD.

Signed-off-by: Dennis Stosberg <dennis@stosberg.net>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-10-02 11:49:45 -07:00
Junio C Hamano
26a063a10b Fix refs.c;:repack_without_ref() clean-up path
The function repack_without_ref() passes a lock-file structure
on the stack to hold_lock_file_for_update(), which in turn
registers it to be cleaned up via atexit().  This is a big
no-no.

This is the same bug James Bottomley fixed with commit
31f584c242.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-10-01 11:41:00 -07:00
Christian Couder
28bed6ea21 Fix a remove_empty_dir_recursive problem.
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-10-01 08:41:58 -07:00
Junio C Hamano
c0277d15ef delete_ref(): delete packed ref
This implements deletion of a packed ref.  Since it is a very
rare event to delete a ref compared to looking up, creating and
updating, this opts to remove the ref from the packed-ref file
instead of doing any of the filesystem based "negative ref" trick
to optimize the deletion path.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-09-30 15:20:44 -07:00
Junio C Hamano
22a3844eba lock_ref_sha1(): check D/F conflict with packed ref when creating.
This makes the ref locking codepath to notice if an existing ref
overlaps with the ref we are creating.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-09-30 15:07:58 -07:00
Junio C Hamano
5cc3cef997 lock_ref_sha1(): do not sometimes error() and sometimes die().
This cleans up the error path in the function so it does not
die() itself sometimes while signalling an error with NULL some
other times which was inconsistent and confusing.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-09-30 15:07:58 -07:00
Junio C Hamano
5e290ff75a refs: minor restructuring of cached refs data.
Once we read packed and loose refs, for_each_ref() and friends
kept using them even after write_ref_sha1() and delete_ref()
changed the refs.  This adds invalidate_cached_refs() as a way
to flush the cached information.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-09-30 15:07:58 -07:00
Junio C Hamano
bc7127ef0f ref locking: allow 'foo' when 'foo/bar' used to exist but not anymore.
It is normal to have .git/refs/heads/foo directory which is
empty after the last branch whose name starts with foo/ is
removed.  Make sure we notice this case and allow creation of
branch foo by removing the empty directory.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-09-30 15:07:58 -07:00
Junio C Hamano
ac5409e420 update-ref: -d flag and ref creation safety.
This adds -d flag to update-ref to allow safe deletion of ref.
Before deleting it, the command checks if the given <oldvalue>
still matches the value the caller thought the ref contained.

Similarly, it also accepts 0{40} or an empty string as <oldvalue>
to allow safe creation of a new ref.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-09-27 02:01:42 -07:00
Junio C Hamano
4431fcc4b1 Clean-up lock-ref implementation
This drops "mustexist" parameter lock_ref_sha1() and lock_any_ref_forupdate()
functions take.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-09-27 01:42:44 -07:00
Junio C Hamano
5fd6f5cffc lock_ref_sha1_basic: remove unused parameter "plen".
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-09-22 21:41:49 -07:00
Petr Baudis
7c1a278d99 Fix buggy ref recording
There is a format string vulnerability introduced with the packed refs
file format.

Signed-off-by: Petr Baudis <pasky@suse.cz>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-09-22 16:53:31 -07:00
Junio C Hamano
8da1977554 Tell between packed, unpacked and symbolic refs.
This adds a "int *flag" parameter to resolve_ref() and makes
for_each_ref() family to call callback function with an extra
"int flag" parameter.  They are used to give two bits of
information (REF_ISSYMREF and REF_ISPACKED) about the ref.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-09-20 22:02:01 -07:00
Junio C Hamano
cb5d709ff8 Add callback data to for_each_ref() family.
This is a long overdue fix to the API for for_each_ref() family
of functions.  It allows the callers to specify a callback data
pointer, so that the caller does not have to use static
variables to communicate with the callback funciton.

The updated for_each_ref() family takes a function of type

	int (*fn)(const char *, const unsigned char *, void *)

and a void pointer as parameters, and calls the function with
the name of the ref and its SHA-1 with the caller-supplied void
pointer as parameters.

The commit updates two callers, builtin-name-rev.c and
builtin-pack-refs.c as an example.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-09-20 21:47:42 -07:00
Petr Baudis
53cce84c05 Fix broken sha1 locking
Current git#next is totally broken wrt. cloning over HTTP, generating refs
at random directories. Of course it's caused by the static get_pathname()
buffer. lock_ref_sha1() stores return value of mkpath()'s get_pathname()
call, then calls lock_ref_sha1_basic() which calls git_path(ref) which
calls get_pathname() at that point returning pointer to the same buffer.
So now you are sprintf()ing a format string into itself, wow! The resulting
pathnames are really cute. (If you've been paying attention, yes, the
mere fact that a format string _could_ write over itself is very wrong
and probably exploitable here. See the other mail I've just sent.)

I've never liked how we use return values of those functions so liberally,
the "allow some random number of get_pathname() return values to work
concurrently" is absolutely horrible pit and we've already fallen in this
before IIRC. I consider it an awful coding practice, you add a call
somewhere and at some other point some distant caller of that breaks since
it reuses the same return values. Not to mention this takes quite some time
to debug.

My gut feeling tells me that there might be more of this.  I don't have
time to review the rest of the users of the refs.c functions though.

Signed-off-by: Petr Baudis <pasky@suse.cz>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-09-20 07:56:03 -07:00
Linus Torvalds
434cd0cd30 Enable the packed refs file format
This actually "turns on" the packed ref file format, now that the
infrastructure to do so sanely exists (ie notably the change to make the
reference reading logic take refnames rather than pathnames to the loose
objects that no longer necessarily even exist).

In particular, when the ref lookup hits a refname that has no loose file
associated with it, it falls back on the packed-ref information. Also, the
ref-locking code, while still using a loose file for the locking itself
(and _creating_ a loose file for the new ref) no longer requires that the
old ref be in such an unpacked state.

Finally, this does a minimal hack to git-checkout.sh to rather than check
the ref-file directly, do a "git-rev-parse" on the "heads/$refname".
That's not really wonderful - we should rather really have a special
routine to verify the names as proper branch head names, but it is a
workable solution for now.

With this, I can literally do something like

	git pack-refs
	find .git/refs -type f -print0 | xargs -0 rm -f --

and the end result is a largely working repository (ie I've done two
commits - which creates _one_ unpacked ref file - done things like run
"gitk" and "git log" etc, and it all looks ok).

There are probably things missing, but I'm hoping that the missing things
are now of the "small and obvious" kind, and that somebody else might want
to start looking at this too. Hint hint ;)

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-09-17 19:09:12 -07:00
Linus Torvalds
ed378ec7e8 Make ref resolution saner
The old code used to totally mix up the notion of a ref-name and the path
that that ref was associated with.  That was not only horribly ugly (a
number of users got the path, and then wanted to try to turn it back into
a ref-name again), but it fundamnetally doesn't work at all once we do any
setup where a ref doesn't have a 1:1 relationship with a particular
pathname.

This fixes things up so that we use the ref-name throughout, and only
turn it into a pathname once we actually look it up in the filesystem.
That makes a lot of things much clearer and more straightforward.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-09-17 19:09:11 -07:00
Linus Torvalds
b37a562a10 Add support for negative refs
You can remove a ref that is packed two different ways: either simply
repack all the refs without that one, or create a loose ref that has the
magic all-zero SHA1.

This also adds back the test that a ref actually has the object it
points to.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-09-17 19:09:11 -07:00
Linus Torvalds
e1e22e37f4 Start handling references internally as a sorted in-memory list
This also adds some very rudimentary support for the notion of packed
refs.  HOWEVER! At this point it isn't used to actually look up a ref
yet, only for listing them (ie "for_each_ref()" and friends see the
packed refs, but none of the other single-ref lookup routines).

Note how we keep two separate lists: one for the loose refs, and one for
the packed refs we read. That's so that we can easily keep the two apart,
and read only one set or the other (and still always make sure that the
loose refs take precedence).

[ From this, it's not actually obvious why we'd keep the two separate
  lists, but it's important to have the packed refs on their own list
  later on, when I add support for looking up a single loose one.

  For that case, we will want to read _just_ the packed refs in case the
  single-ref lookup fails, yet we may end up needing the other list at
  some point in the future, so keeping them separated is important ]

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-09-17 19:09:11 -07:00
Shawn Pearce
9befac470b Replace uses of strdup with xstrdup.
Like xmalloc and xrealloc xstrdup dies with a useful message if
the native strdup() implementation returns NULL rather than a
valid pointer.

I just tried to use xstrdup in new code and found it to be missing.
However I expected it to be present as xmalloc and xrealloc are
already commonly used throughout the code.

[jc: removed the part that deals with last_XXX, which I am
 finding more and more dubious these days.]

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-09-02 03:24:37 -07:00
Junio C Hamano
4cac42b132 free(NULL) is perfectly valid.
Jonas noticed some places say "if (X) free(X)" which is totally
unnecessary.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-08-27 21:19:39 -07:00
Shawn Pearce
e702496e43 Convert memcpy(a,b,20) to hashcpy(a,b).
This abstracts away the size of the hash values when copying them
from memory location to memory location, much as the introduction
of hashcmp abstracted away hash value comparsion.

A few call sites were using char* rather than unsigned char* so
I added the cast rather than open hashcpy to be void*.  This is a
reasonable tradeoff as most call sites already use unsigned char*
and the existing hashcmp is also declared to be unsigned char*.

[jc: Splitted the patch to "master" part, to be followed by a
 patch for merge-recursive.c which is not in "master" yet.

 Fixed the cast in the latter hunk to combine-diff.c which was
 wrong in the original.

 Also converted ones left-over in combine-diff.c, diff-lib.c and
 upload-pack.c ]

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-08-23 13:53:10 -07:00
David Rientjes
a89fccd281 Do not use memcmp(sha1_1, sha1_2, 20) with hardcoded length.
Introduces global inline:

	hashcmp(const unsigned char *sha1, const unsigned char *sha2)

Uses memcmp for comparison and returns the result based on the length of
the hash name (a future runtime decision).

Acked-by: Alex Riesen <raa.lkml@gmail.com>
Signed-off-by: David Rientjes <rientjes@google.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-08-17 14:23:53 -07:00
Junio C Hamano
40aaae88ad Better error message when we are unable to lock the index file
Most of the callers except the one in refs.c use the function to
update the index file.  Among the index writers, everybody
except write-tree dies if they cannot open it for writing.

This gives the function an extra argument, to tell it to die
when it cannot create a new file as the lockfile.

The only caller that does not have to die is write-tree, because
updating the index for the cache-tree part is optional and not
being able to do so does not affect the correctness.  I think we
do not have to be so careful and make the failure into die() the
same way as other callers, but that would be a different patch.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-08-12 17:08:25 -07:00
Rene Scharfe
5bb1cda5f7 drop length argument of has_extension
As Fredrik points out the current interface of has_extension() is
potentially confusing.  Its parameters include both a nul-terminated
string and a length-limited string.

This patch drops the length argument, requiring two nul-terminated
strings; all callsites are updated.  I checked that all of them indeed
provide nul-terminated strings.  Filenames need to be nul-terminated
anyway if they are to be passed to open() etc.  The performance penalty
of the additional strlen() is negligible compared to the system calls
which inevitably surround has_extension() calls.

Additionally, change has_extension() to use size_t inside instead of
int, as that is the exact type strlen() returns and memcmp() expects.

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-08-11 16:06:34 -07:00
Rene Scharfe
83a2b841d6 Add has_extension()
The little helper has_extension() documents through its name what we are
trying to do and makes sure we don't forget the underrun check.

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-08-10 14:13:53 -07:00
Shawn Pearce
818f477c40 Display an error from update-ref if target ref name is invalid.
Alex Riesen (raa.lkml@gmail.com) recently observed that git branch
would fail with no error message due to unexpected situations with
regards to refs.  For example, if .git/refs/heads/gu is a file but
"git branch -b refs/heads/gu/fixa HEAD" was invoked by the user
it would fail silently due to refs/heads/gu being a file and not
a directory.

This change adds a test for trying to create a ref within a directory
that is actually currently a file, and adds error printing within
the ref locking routine should the resolve operation fail.

The error printing code probably belongs at this level of the library
as other failures within the ref locking, writing and logging code
are also currently at this level of the code.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-07-28 20:53:53 -07:00
Shawn Pearce
0b0fe4a65d Allow user.name and user.email to drive reflog entry.
Apparently calling setup_ident() after git_config causes the
user.name and user.email values read from the config file to be
replaced with the data obtained from the host.  This means that
users who have setup their email address in user.email will instead
be writing reflog entries with their hostname.

Moving setup_ident() to before git_config in update-ref resolves
this ordering problem.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-07-10 21:12:40 -07:00
Alp Toker
ff4c848527 Fix typos involving the word 'commit'
Signed-off-by: Alp Toker <alp@atoker.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-07-09 03:31:36 -07:00
Junio C Hamano
138086a725 shared repository - add a few missing calls to adjust_shared_perm().
There were a few calls to adjust_shared_perm() that were
missing:

 - init-db creates refs, refs/heads, and refs/tags before
   reading from templates that could specify sharedrepository in
   the config file;

 - updating config file created it under user's umask without
   adjusting;

 - updating refs created it under user's umask without
   adjusting;

 - switching branches created .git/HEAD under user's umask
   without adjusting.

This moves adjust_shared_perm() from sha1_file.c to path.c,
since a few SIMPLE_PROGRAM need to call repository configuration
functions which in turn need to call adjust_shared_perm().
sha1_file.c needs to link with SHA1 computation library which
is usually not linked to SIMPLE_PROGRAM.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-06-09 22:15:50 -07:00