Re: [PATCH v3] sha1_file: do not add own object directory as alternate

2014-07-16 Thread Ephrim Khong

On 15.07.2014 21:26, Junio C Hamano wrote:

+   strbuf_addstr(objdirbuf, absolute_path(get_object_directory()));
+   normalize_path_copy(objdirbuf.buf, objdirbuf.buf);


This is somewhat a strange usage of a strbuf.


There might be a more elegant way, but I tried to mimic the local coding 
style and simply copied how the alternate paths were normalized. Let me 
know if you want this re-rolled without strbuf, otherwise I'll leave it 
as-is.



diff --git a/t/t7702-repack-cyclic-alternate.sh 
b/t/t7702-repack-cyclic-alternate.sh
new file mode 100755
index 000..8341d46
--- /dev/null
+++ b/t/t7702-repack-cyclic-alternate.sh


Do we really have to waste a new test file only for this test?


Absolutely not. I'll add it to 7700, which seems appropriate.

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


Re: [PATCH v3] sha1_file: do not add own object directory as alternate

2014-07-16 Thread Ephrim Khong

On 15.07.2014 21:48, Junio C Hamano wrote:

Ephrim Khong dr.kh...@gmail.com writes:

+test_expect_success setup '
+   GIT_OBJECT_DIRECTORY=.git//../.git/objects 
+   export GIT_OBJECT_DIRECTORY 


Do you need this artificially strange environment settings for the
problem to manifest itself, or is it sufficient to have a
non-canonical pathname in the info/alternates file?


The test should check the normalization of both the paths in 
info/alternates and of GIT_OBJECT_DIRECTORY, so I'd prefer to leave it 
in. It is not necessary to reproduce the original problem, though.



Exporting an environment early in the test and having later tests in
the file depend on it makes it harder to debug when things go wrong,
than leaving an info/alternates file in the repository, primarily
because the latter can be inspected more easily in the trash
directory after t7702-*.sh -i dies, hence the above question.


That sounds reasonable. The variable is not required at the 
initialization anyway, so I'll set it right before the actual test and 
wrap it into a subshell to make debugging easier.

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


[PATCH] annotate: use argv_array

2014-07-16 Thread René Scharfe
Simplify the code and get rid of some magic constants by using
argv_array to build the argument list for cmd_blame.  Be lazy and let
the OS release our allocated memory, as before.

Signed-off-by: Rene Scharfe l@web.de
---
 builtin/annotate.c | 12 +---
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/builtin/annotate.c b/builtin/annotate.c
index fc43eed..da413ae 100644
--- a/builtin/annotate.c
+++ b/builtin/annotate.c
@@ -5,20 +5,18 @@
  */
 #include git-compat-util.h
 #include builtin.h
+#include argv-array.h
 
 int cmd_annotate(int argc, const char **argv, const char *prefix)
 {
-   const char **nargv;
+   struct argv_array args = ARGV_ARRAY_INIT;
int i;
-   nargv = xmalloc(sizeof(char *) * (argc + 2));
 
-   nargv[0] = annotate;
-   nargv[1] = -c;
+   argv_array_pushl(args, annotate, -c, NULL);
 
for (i = 1; i  argc; i++) {
-   nargv[i+1] = argv[i];
+   argv_array_push(args, argv[i]);
}
-   nargv[argc + 1] = NULL;
 
-   return cmd_blame(argc + 1, nargv, prefix);
+   return cmd_blame(args.argc, args.argv, prefix);
 }
-- 
2.0.0

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


Re: [PATCH 0/3] fix test suite with mingw-unicode patches

2014-07-16 Thread Stepan Kasal
Hello Karsten,

thanks for your analysis.  Most of the patches you refer to are simply
switching off tests for MINGW; let me comment on the remaining ones:

 * t0110-urlmatch-normalization: 1
 
 Passing binary data on the command line...would have to
 teach test-urlmatch-normalization.c to read from stdin or file.
 https://github.com/msysgit/git/commit/be0d6dee

Indeed, that would be better solution.  For now, I'm going to submit the
switch-off patch you mention.

 * t4036-format-patch-signer-mime: 1
 
 Passing non-ASCII by environment variable, will be fixed by Unicode
 environment support.

Will submit that patch series soon.

 * t7001-mv: 6
 cp -P fails in MinGW - perhaps use the long option forms (--no-dereference)?

cp -P fails with our 2001-edition of cp, so msysgit had to revert:
https://github.com/msysgit/git/commit/6d3e23d4

But I was ashamed to mention that upstream; and I hope mingwGitDevEnv is
going to solve that.

 * t8001-annotate/t8002-blame: 5
 
 Msys.dll thinks '-L/regex/' is an absolute path and expands to 
 '-LC:/msysgit/regex/'.
 https://github.com/msysgit/git/commit/2d52168a

Nice!  But I'm afraid the patch cannot be submitted upstream as it is.

I think the hack could be automated by processing options -L* this way:
sed 'sX\(^-L\|,\)\^\?/X\\;*Xg'
Then it would become only few lines at the top of the script, executed
on mingw only.
I hope to submit the patch in this form soon.

Have a nice day,
Stepan
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v8 4/4] cache-tree: Write updated cache-tree after commit

2014-07-16 Thread Duy Nguyen
On Tue, Jul 15, 2014 at 11:45 PM, Junio C Hamano gits...@pobox.com wrote:
 What is the real point of writing into *.lock and renaming?  It
 serves two purposes: (1) everybody adheres to that convention---if
 we managed to take the lock index.lock, nobody else will compete
 and interfere with us until we rename it to index. (2) in the
 meantime, others can still read the old contents in the original
 index.

 With take lock, write to a temporary, commit by rename or
 rollback by delete, we can have the usual transactional semantics.
 While we are working on it, nobody is allowed to muck with the same
 file, because everybody pays attention to *.lock.  People will not
 see what we are doing until we release the lock because we are not
 writing into the primary file.  And people can see what we did in
 its entirety once we are done because we close and rename to commit
 our changes atomically.

True.

 Think what CLOSE_LOCK adds to that and you would appreciate its
 usefulness and at the same time realize its limitation.  By allowing
 us to flush what we wrote to the disk without releasing the lock, we
 can give others (e.g. subprograms we spawn) controlled access to the
 new contents we prepared before we commit the result to the outside
 world.  The access is controlled because we are in control when we
 tell these others to peek into or update the temporary file *.lock.

 The original implementaiton of CLOSE_LOCK is limited in that you can
 do so only once; you take a lock, you do your thing, you close, you
 let (one or more) others see it, and you commit (or rollback).  You
 cannot do another of your thing once you close with the original
 implementation because there was no way to reopen.

This is probably where our opinions differ. Yes, if you are sure
nobody else is looking at the lock file any more, then you can do
whatever you want. And because this is a .lock file, nobody is
supposed to look at it unless you tell them too (in contrast
$GIT_DIR/index can be read at any time). The format of the index makes
it impossible to just edit one byte and be done with it. You always
write a full new file. By sticking to transaction-style update, you
need no extra code, and you have a back up file as a side effect.

 What do you gain by your proposal to lock index.lock file?  We
 know we already have index.lock, so nobody should be competing on
 mucking with its contents with us and we gain nothing by writing
 into index.lock.lock and renaming it to index.lock.  We are in total
 control of the lifetime of index.lock, when we spawn subprograms on
 it to let them write to it, when we ourselves write to it, when we
 spawn subprograms on it to let them read from it, all under the lock
 we have on the index, i.e. index.lock.

 The only thing use of another temporary file (that does not have to
 be a lock on index.lock, by the way, because we have total control
 over when and who updates the file while we hold the index.lock)
 would give you is that it allows you to make the success of the do
 another of your thing step optional.  While holding the lock, you
 close and let add -i work on it, and after it returns, instead of
 reopening, you write into yet another index.lock.lock, expecting
 that it might fail and when it fails you can roll it back, leaving
 the contents add -i left in index.lock intact.  If you do not
 use the extra temporary file, you start from index.lock left by
 add -i, write the updated index into index.lock and if you fail
 to write, you have to roll back the entire index---you lose the
 option to use the index left by add -i without repopulated
 cache-tree.  But in the index update context, I do not think such a
 complexity is not necessary.  If something fails, we should fail and
 roll back the entire index.

I probably look at the problem from a wrong angle. To me the result of
commit -p is precious. I'm not a big user of commit -p myself as I
prefer add -p but it's the same: it'd be frustrating if after you
have carefully added your chunks, the program aborts and you have to
start over. And not just a few chunks. Think of reviewing .po files
and approve strings by the means of adding them to the index. Perhaps
because _I_ as a developer see this cache-tree update step optional
and react to it unnecessarily. Ordinary users won't see any
difference. And perhaps a better way to save the result of commit/add
-p is some sort of index log, not be over-protective at this
interactive commit code block.

I don't feel strongly either way. So your call.
-- 
Duy
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/2] config: use chmod() instead of fchmod()

2014-07-16 Thread Karsten Blees
Am 16.07.2014 07:33, schrieb Johannes Sixt:
 Am 16.07.2014 00:54, schrieb Karsten Blees:
 There is no fchmod() on native Windows platforms (MinGW and MSVC), and the
 equivalent Win32 API (SetFileInformationByHandle) requires Windows Vista.

 Use chmod() instead.

 Signed-off-by: Karsten Blees bl...@dcon.de
 ---
  config.c | 8 
  1 file changed, 4 insertions(+), 4 deletions(-)

 diff --git a/config.c b/config.c
 index ba882a1..9767c4b 100644
 --- a/config.c
 +++ b/config.c
 @@ -1636,8 +1636,8 @@ int git_config_set_multivar_in_file(const char 
 *config_filename,
  MAP_PRIVATE, in_fd, 0);
  close(in_fd);
  
 -if (fchmod(fd, st.st_mode  0)  0) {
 -error(fchmod on %s failed: %s,
 +if (chmod(lock-filename, st.st_mode  0)  0) {
 +error(chmod on %s failed: %s,
  lock-filename, strerror(errno));
  ret = CONFIG_NO_WRITE;
  goto out_free;
 @@ -1815,8 +1815,8 @@ int git_config_rename_section_in_file(const char 
 *config_filename,
  
  fstat(fileno(config_file), st);
  
 -if (fchmod(out_fd, st.st_mode  0)  0) {
 -ret = error(fchmod on %s failed: %s,
 +if (chmod(lock-filename, st.st_mode  0)  0) {
 +ret = error(chmod on %s failed: %s,
  lock-filename, strerror(errno));
  goto out;
  }

 
 I assume you tested this patch on Windows. I am mildly surprised that
 (on Windows) chmod() works on a file that is still open.
 
 -- Hannes
 

Yes, file attributes can be set independently of open files. In fact, existing
code in git already does that in many places (via adjust_shared_perm(), which
is typically called while the file is open).
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


diff.renameLimit biting/silently ignored in cherry-pick

2014-07-16 Thread Andreas Krey
Hi all,

we're running into a problem with the rename detection; we're
at num_src=27320 and num_create=46731, which means that 'matrix'
would still be enumerable in int32, but... well, I don't yet know
where exactly it refuses to perform rename detection. I've tried to
set needed_rename_limit to 2^31-2 at the place where it was set to the
maximum of num_src and num_create, but that doesn't help. Where could
I affect this?

Also we have the impression that 'git cherry-pick' silently stops
doing rename detection in this situation - it doesn't take nearly
long enough to perform it, and it clearly misses renames.

I'm trying to do a 'diff --name-status -M' to see whether the
rename is properly detected, but I guess the real way would
be to make cherry-pick still perform rename detection, and
to find out how to do *that*.

Cheers,

Andreas

-- 
Totally trivial. Famous last words.
From: Linus Torvalds torvalds@*.org
Date: Fri, 22 Jan 2010 07:29:21 -0800
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 0/3] fix test suite with mingw-unicode patches

2014-07-16 Thread Thomas Braun
Am 16.07.2014 11:29, schrieb Stepan Kasal:
 * t7001-mv: 6
 cp -P fails in MinGW - perhaps use the long option forms (--no-dereference)?
 
 cp -P fails with our 2001-edition of cp, so msysgit had to revert:
 https://github.com/msysgit/git/commit/6d3e23d4
 
 But I was ashamed to mention that upstream; and I hope mingwGitDevEnv is
 going to solve that.

Yes it does. cp in mingwGitDevEnv is from coreutils 5.97 and knows about -P.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v9r1 1/2] add `config_set` API for caching config-like files

2014-07-16 Thread Tanay Abhra
Currently `git_config()` uses a callback mechanism and file rereads for
config values. Due to this approach, it is not uncommon for the config
files to be parsed several times during the run of a git program, with
different callbacks picking out different variables useful to themselves.

Add a `config_set`, that can be used to construct an in-memory cache for
config-like files that the caller specifies (i.e., files like `.gitmodules`,
`~/.gitconfig` etc.). Add two external functions `git_configset_get_value`
and `git_configset_get_value_multi` for querying from the config sets.
`git_configset_get_value` follows `last one wins` semantic (i.e. if there
are multiple matches for the queried key in the files of the configset the
value returned will be the last entry in `value_list`).
`git_configset_get_value_multi` returns a list of values sorted in order of
increasing priority (i.e. last match will be at the end of the list). Add
type specific query functions like `git_configset_get_bool` and similar.

Add a default `config_set`, `the_config_set` to cache all key-value pairs
read from usual config files (repo specific .git/config, user wide
~/.gitconfig, XDG config and the global /etc/gitconfig). `the_config_set`
is populated using `git_config()`.

Add two external functions `git_config_get_value` and
`git_config_get_value_multi` for querying in a non-callback manner from
`the_config_set`. Also, add type specific query functions that are
implemented as a thin wrapper around the `config_set` API.

Signed-off-by: Matthieu Moy matthieu@imag.fr
Signed-off-by: Tanay Abhra tanay...@gmail.com
---
 Documentation/technical/api-config.txt | 137 +
 cache.h|  30 
 config.c   | 264 +
 3 files changed, 431 insertions(+)

diff --git a/Documentation/technical/api-config.txt 
b/Documentation/technical/api-config.txt
index 230b3a0..fc0e379 100644
--- a/Documentation/technical/api-config.txt
+++ b/Documentation/technical/api-config.txt
@@ -77,6 +77,81 @@ To read a specific file in git-config format, use
 `git_config_from_file`. This takes the same callback and data parameters
 as `git_config`.

+Querying For Specific Variables
+---
+
+For programs wanting to query for specific variables in a non-callback
+manner, the config API provides two functions `git_config_get_value`
+and `git_config_get_value_multi`. They both read values from an internal
+cache generated previously from reading the config files.
+
+`int git_config_get_value(const char *key, const char **value)`::
+
+   Finds the highest-priority value for the configuration variable `key`,
+   stores the pointer to it in `value` and returns 0. When the
+   configuration variable `key` is not found, returns 1 without touching
+   `value`. The caller should not free or modify `value`, as it is owned
+   by the cache.
+
+`const struct string_list *git_config_get_value_multi(const char *key)`::
+
+   Finds and returns the value list, sorted in order of increasing priority
+   for the configuration variable `key`. When the configuration variable
+   `key` is not found, returns NULL. The caller should not free or modify
+   the returned pointer, as it is owned by the cache.
+
+`void git_config_clear(void)`::
+
+   Resets and invalidates the config cache.
+
+The config API also provides type specific API functions which do conversion
+as well as retrieval for the queried variable, including:
+
+`int git_config_get_int(const char *key, int *dest)`::
+
+   Finds and parses the value to an integer for the configuration variable
+   `key`. Dies on error; otherwise, stores the value of the parsed integer 
in
+   `dest` and returns 0. When the configuration variable `key` is not 
found,
+   returns 1 without touching `dest`.
+
+`int git_config_get_ulong(const char *key, unsigned long *dest)`::
+
+   Similar to `git_config_get_int` but for unsigned longs.
+
+`int git_config_get_bool(const char *key, int *dest)`::
+
+   Finds and parses the value into a boolean value, for the configuration
+   variable `key` respecting keywords like true and false. Integer
+   values are converted into true/false values (when they are non-zero or
+   zero, respectively). Other values cause a die(). If parsing is 
successful,
+   stores the value of the parsed result in `dest` and returns 0. When the
+   configuration variable `key` is not found, returns 1 without touching
+   `dest`.
+
+`int git_config_get_bool_or_int(const char *key, int *is_bool, int *dest)`::
+
+   Similar to `git_config_get_bool`, except that integers are copied as-is,
+   and `is_bool` flag is unset.
+
+`int git_config_get_maybe_bool(const char *key, int *dest)`::
+
+   Similar to `git_config_get_bool`, except that it returns -1 on error
+   rather than dying.
+
+`int 

[PATCH v9r1 2/2] test-config: add tests for the config_set API

2014-07-16 Thread Tanay Abhra
Expose the `config_set` C API as a set of simple commands in order to
facilitate testing. Add tests for the `config_set` API as well as for
`git_config_get_*()` family for the usual config files.

Signed-off-by: Matthieu Moy matthieu@imag.fr
Signed-off-by: Tanay Abhra tanay...@gmail.com
---
 .gitignore|   1 +
 Makefile  |   1 +
 t/t1308-config-set.sh | 200 ++
 test-config.c | 140 +++
 4 files changed, 342 insertions(+)
 create mode 100755 t/t1308-config-set.sh
 create mode 100644 test-config.c

diff --git a/.gitignore b/.gitignore
index 42294e5..7677533 100644
--- a/.gitignore
+++ b/.gitignore
@@ -177,6 +177,7 @@
 /gitweb/static/gitweb.min.*
 /test-chmtime
 /test-ctype
+/test-config
 /test-date
 /test-delta
 /test-dump-cache-tree
diff --git a/Makefile b/Makefile
index b92418d..e070eb8 100644
--- a/Makefile
+++ b/Makefile
@@ -549,6 +549,7 @@ PROGRAMS += $(patsubst %.o,git-%$X,$(PROGRAM_OBJS))

 TEST_PROGRAMS_NEED_X += test-chmtime
 TEST_PROGRAMS_NEED_X += test-ctype
+TEST_PROGRAMS_NEED_X += test-config
 TEST_PROGRAMS_NEED_X += test-date
 TEST_PROGRAMS_NEED_X += test-delta
 TEST_PROGRAMS_NEED_X += test-dump-cache-tree
diff --git a/t/t1308-config-set.sh b/t/t1308-config-set.sh
new file mode 100755
index 000..cf8f2d7
--- /dev/null
+++ b/t/t1308-config-set.sh
@@ -0,0 +1,200 @@
+#!/bin/sh
+
+test_description='Test git config-set API in different settings'
+
+. ./test-lib.sh
+
+# 'check_config get_* section.key value' verifies that the entry for
+# section.key is 'value'
+check_config () {
+   if test $1 = expect_code
+   then
+   expect_code=$2  shift  shift
+   else
+   expect_code=0
+   fi 
+   op=$1 key=$2  shift  shift
+   if test $# != 0
+   then
+   printf %s\n $@
+   fi expect 
+   test_expect_code $expect_code test-config $op $key actual 
+   test_cmp expect actual
+}
+
+test_expect_success 'setup default config' '
+   cat .git/config \EOF
+   [case]
+   penguin = very blue
+   Movie = BadPhysics
+   UPPERCASE = true
+   MixedCase = true
+   my =
+   foo
+   baz = sam
+   [Cores]
+   WhatEver = Second
+   baz = bar
+   [cores]
+   baz = bat
+   [CORES]
+   baz = ball
+   [my Foo bAr]
+   hi = mixed-case
+   [my FOO BAR]
+   hi = upper-case
+   [my foo bar]
+   hi = lower-case
+   [case]
+   baz = bat
+   baz = hask
+   [lamb]
+   chop = 65
+   head = none
+   [goat]
+   legs = 4
+   head = true
+   skin = false
+   nose = 1
+   horns
+   EOF
+'
+
+test_expect_success 'get value for a simple key' '
+   check_config get_value case.penguin very blue
+'
+
+test_expect_success 'get value for a key with value as an empty string' '
+   check_config get_value case.my 
+'
+
+test_expect_success 'get value for a key with value as NULL' '
+   check_config get_value case.foo (NULL)
+'
+
+test_expect_success 'upper case key' '
+   check_config get_value case.UPPERCASE true 
+   check_config get_value case.uppercase true
+'
+
+test_expect_success 'mixed case key' '
+   check_config get_value case.MixedCase true 
+   check_config get_value case.MIXEDCASE true 
+   check_config get_value case.mixedcase true
+'
+
+test_expect_success 'key and value with mixed case' '
+   check_config get_value case.Movie BadPhysics
+'
+
+test_expect_success 'key with case sensitive subsection' '
+   check_config get_value my.Foo bAr.hi mixed-case 
+   check_config get_value my.FOO BAR.hi upper-case 
+   check_config get_value my.foo bar.hi lower-case
+'
+
+test_expect_success 'key with case insensitive section header' '
+   check_config get_value cores.baz ball 
+   check_config get_value Cores.baz ball 
+   check_config get_value CORES.baz ball 
+   check_config get_value coreS.baz ball
+'
+
+test_expect_success 'key with case insensitive section header  variable' '
+   check_config get_value CORES.BAZ ball 
+   check_config get_value cores.baz ball 
+   check_config get_value cores.BaZ ball 
+   check_config get_value cOreS.bAz ball
+'
+
+test_expect_success 'find value with misspelled key' '
+   check_config expect_code 1 get_value my.fOo Bar.hi Value not found 
for \my.fOo Bar.hi\
+'
+
+test_expect_success 'find value with the highest priority' '
+   check_config get_value case.baz hask
+'
+
+test_expect_success 'find integer value for a key' '
+   check_config get_int lamb.chop 65
+'
+
+test_expect_success 'find integer if value is non parse-able' '
+   check_config expect_code 128 get_int lamb.head
+'
+
+test_expect_success 

Re: [PATCH v9r1 2/2] test-config: add tests for the config_set API

2014-07-16 Thread Matthieu Moy
Tanay Abhra tanay...@gmail.com writes:

 +# 'check_config get_* section.key value' verifies that the entry for
 +# section.key is 'value'
 +check_config () {
 + if test $1 = expect_code
 + then
 + expect_code=$2  shift  shift
 + else
 + expect_code=0
 + fi 
 + op=$1 key=$2  shift  shift
 + if test $# != 0

Broken -chain after shift.

(No time for more review right now, but I'll have time in ~3h from now)

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v9r2 1/2] add `config_set` API for caching config-like files

2014-07-16 Thread Tanay Abhra
Currently `git_config()` uses a callback mechanism and file rereads for
config values. Due to this approach, it is not uncommon for the config
files to be parsed several times during the run of a git program, with
different callbacks picking out different variables useful to themselves.

Add a `config_set`, that can be used to construct an in-memory cache for
config-like files that the caller specifies (i.e., files like `.gitmodules`,
`~/.gitconfig` etc.). Add two external functions `git_configset_get_value`
and `git_configset_get_value_multi` for querying from the config sets.
`git_configset_get_value` follows `last one wins` semantic (i.e. if there
are multiple matches for the queried key in the files of the configset the
value returned will be the last entry in `value_list`).
`git_configset_get_value_multi` returns a list of values sorted in order of
increasing priority (i.e. last match will be at the end of the list). Add
type specific query functions like `git_configset_get_bool` and similar.

Add a default `config_set`, `the_config_set` to cache all key-value pairs
read from usual config files (repo specific .git/config, user wide
~/.gitconfig, XDG config and the global /etc/gitconfig). `the_config_set`
is populated using `git_config()`.

Add two external functions `git_config_get_value` and
`git_config_get_value_multi` for querying in a non-callback manner from
`the_config_set`. Also, add type specific query functions that are
implemented as a thin wrapper around the `config_set` API.

Signed-off-by: Matthieu Moy matthieu@imag.fr
Signed-off-by: Tanay Abhra tanay...@gmail.com
 Documentation/technical/api-config.txt | 137 +
 cache.h|  30 
 config.c   | 264 +
 3 files changed, 431 insertions(+)

diff --git a/Documentation/technical/api-config.txt 
b/Documentation/technical/api-config.txt
index 230b3a0..fc0e379 100644
--- a/Documentation/technical/api-config.txt
+++ b/Documentation/technical/api-config.txt
@@ -77,6 +77,81 @@ To read a specific file in git-config format, use
 `git_config_from_file`. This takes the same callback and data parameters
 as `git_config`.

+Querying For Specific Variables
+---
+
+For programs wanting to query for specific variables in a non-callback
+manner, the config API provides two functions `git_config_get_value`
+and `git_config_get_value_multi`. They both read values from an internal
+cache generated previously from reading the config files.
+
+`int git_config_get_value(const char *key, const char **value)`::
+
+   Finds the highest-priority value for the configuration variable `key`,
+   stores the pointer to it in `value` and returns 0. When the
+   configuration variable `key` is not found, returns 1 without touching
+   `value`. The caller should not free or modify `value`, as it is owned
+   by the cache.
+
+`const struct string_list *git_config_get_value_multi(const char *key)`::
+
+   Finds and returns the value list, sorted in order of increasing priority
+   for the configuration variable `key`. When the configuration variable
+   `key` is not found, returns NULL. The caller should not free or modify
+   the returned pointer, as it is owned by the cache.
+
+`void git_config_clear(void)`::
+
+   Resets and invalidates the config cache.
+
+The config API also provides type specific API functions which do conversion
+as well as retrieval for the queried variable, including:
+
+`int git_config_get_int(const char *key, int *dest)`::
+
+   Finds and parses the value to an integer for the configuration variable
+   `key`. Dies on error; otherwise, stores the value of the parsed integer 
in
+   `dest` and returns 0. When the configuration variable `key` is not 
found,
+   returns 1 without touching `dest`.
+
+`int git_config_get_ulong(const char *key, unsigned long *dest)`::
+
+   Similar to `git_config_get_int` but for unsigned longs.
+
+`int git_config_get_bool(const char *key, int *dest)`::
+
+   Finds and parses the value into a boolean value, for the configuration
+   variable `key` respecting keywords like true and false. Integer
+   values are converted into true/false values (when they are non-zero or
+   zero, respectively). Other values cause a die(). If parsing is 
successful,
+   stores the value of the parsed result in `dest` and returns 0. When the
+   configuration variable `key` is not found, returns 1 without touching
+   `dest`.
+
+`int git_config_get_bool_or_int(const char *key, int *is_bool, int *dest)`::
+
+   Similar to `git_config_get_bool`, except that integers are copied as-is,
+   and `is_bool` flag is unset.
+
+`int git_config_get_maybe_bool(const char *key, int *dest)`::
+
+   Similar to `git_config_get_bool`, except that it returns -1 on error
+   rather than dying.
+
+`int 

[PATCH v9r2 2/2] test-config: add tests for the config_set API

2014-07-16 Thread Tanay Abhra
Expose the `config_set` C API as a set of simple commands in order to
facilitate testing. Add tests for the `config_set` API as well as for
`git_config_get_*()` family for the usual config files.

Signed-off-by: Matthieu Moy matthieu@imag.fr
Signed-off-by: Tanay Abhra tanay...@gmail.com
---
 .gitignore|   1 +
 Makefile  |   1 +
 t/t1308-config-set.sh | 200 ++
 test-config.c | 140 +++
 4 files changed, 342 insertions(+)
 create mode 100755 t/t1308-config-set.sh
 create mode 100644 test-config.c

diff --git a/.gitignore b/.gitignore
index edb1dcf..fcdee42 100644
--- a/.gitignore
+++ b/.gitignore
@@ -178,6 +178,7 @@
 /gitweb/static/gitweb.min.*
 /test-chmtime
 /test-ctype
+/test-config
 /test-date
 /test-delta
 /test-dump-cache-tree
diff --git a/Makefile b/Makefile
index b92418d..e070eb8 100644
--- a/Makefile
+++ b/Makefile
@@ -549,6 +549,7 @@ PROGRAMS += $(patsubst %.o,git-%$X,$(PROGRAM_OBJS))

 TEST_PROGRAMS_NEED_X += test-chmtime
 TEST_PROGRAMS_NEED_X += test-ctype
+TEST_PROGRAMS_NEED_X += test-config
 TEST_PROGRAMS_NEED_X += test-date
 TEST_PROGRAMS_NEED_X += test-delta
 TEST_PROGRAMS_NEED_X += test-dump-cache-tree
diff --git a/t/t1308-config-set.sh b/t/t1308-config-set.sh
new file mode 100755
index 000..4752fd9
--- /dev/null
+++ b/t/t1308-config-set.sh
@@ -0,0 +1,200 @@
+#!/bin/sh
+
+test_description='Test git config-set API in different settings'
+
+. ./test-lib.sh
+
+# 'check_config get_* section.key value' verifies that the entry for
+# section.key is 'value'
+check_config () {
+   if test $1 = expect_code
+   then
+   expect_code=$2  shift  shift
+   else
+   expect_code=0
+   fi 
+   op=$1 key=$2  shift  shift 
+   if test $# != 0
+   then
+   printf %s\n $@
+   fi expect 
+   test_expect_code $expect_code test-config $op $key actual 
+   test_cmp expect actual
+}
+
+test_expect_success 'setup default config' '
+   cat .git/config \EOF
+   [case]
+   penguin = very blue
+   Movie = BadPhysics
+   UPPERCASE = true
+   MixedCase = true
+   my =
+   foo
+   baz = sam
+   [Cores]
+   WhatEver = Second
+   baz = bar
+   [cores]
+   baz = bat
+   [CORES]
+   baz = ball
+   [my Foo bAr]
+   hi = mixed-case
+   [my FOO BAR]
+   hi = upper-case
+   [my foo bar]
+   hi = lower-case
+   [case]
+   baz = bat
+   baz = hask
+   [lamb]
+   chop = 65
+   head = none
+   [goat]
+   legs = 4
+   head = true
+   skin = false
+   nose = 1
+   horns
+   EOF
+'
+
+test_expect_success 'get value for a simple key' '
+   check_config get_value case.penguin very blue
+'
+
+test_expect_success 'get value for a key with value as an empty string' '
+   check_config get_value case.my 
+'
+
+test_expect_success 'get value for a key with value as NULL' '
+   check_config get_value case.foo (NULL)
+'
+
+test_expect_success 'upper case key' '
+   check_config get_value case.UPPERCASE true 
+   check_config get_value case.uppercase true
+'
+
+test_expect_success 'mixed case key' '
+   check_config get_value case.MixedCase true 
+   check_config get_value case.MIXEDCASE true 
+   check_config get_value case.mixedcase true
+'
+
+test_expect_success 'key and value with mixed case' '
+   check_config get_value case.Movie BadPhysics
+'
+
+test_expect_success 'key with case sensitive subsection' '
+   check_config get_value my.Foo bAr.hi mixed-case 
+   check_config get_value my.FOO BAR.hi upper-case 
+   check_config get_value my.foo bar.hi lower-case
+'
+
+test_expect_success 'key with case insensitive section header' '
+   check_config get_value cores.baz ball 
+   check_config get_value Cores.baz ball 
+   check_config get_value CORES.baz ball 
+   check_config get_value coreS.baz ball
+'
+
+test_expect_success 'key with case insensitive section header  variable' '
+   check_config get_value CORES.BAZ ball 
+   check_config get_value cores.baz ball 
+   check_config get_value cores.BaZ ball 
+   check_config get_value cOreS.bAz ball
+'
+
+test_expect_success 'find value with misspelled key' '
+   check_config expect_code 1 get_value my.fOo Bar.hi Value not found 
for \my.fOo Bar.hi\
+'
+
+test_expect_success 'find value with the highest priority' '
+   check_config get_value case.baz hask
+'
+
+test_expect_success 'find integer value for a key' '
+   check_config get_int lamb.chop 65
+'
+
+test_expect_success 'find integer if value is non parse-able' '
+   check_config expect_code 128 get_int lamb.head
+'
+
+test_expect_success 

Re: Big repository cannot be reduced

2014-07-16 Thread Michael Haggerty
On 07/15/2014 09:43 AM, Woody Wu wrote:
 I have tried some methods introduced in the network, but always
 failed.  Some big files committed by me to a very old branch then the
 files deleted and new branches were continuously created. Now the
 checkout directory has grown to about 80 megabytes.  What's the right
 way to permenently erase those garbage big files?

You probably need to use git filter-branch or maybe BFG
(http://rtyley.github.io/bfg-repo-cleaner/) to rewrite history as if the
big files had never been committed.  But beware of the warnings about
rewriting history--for example, any collaborators will have to rebase
their branches onto the new history.

Michael

-- 
Michael Haggerty
mhag...@alum.mit.edu
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v1] rebase -p: Command line option --no-ff is ignored

2014-07-16 Thread Fabian Ruch
Hi Marc,

I forgot to cc your mailbox when I posted this patch last week. Do you
still remember whether there was a particular reason why
pick_one_preserving_merges wasn't touched by the commit b499549 (Teach
rebase the --no-ff option.), by any chance?

Kind regards,
   Fabian

Fabian Ruch writes:
 The --no-ff option instructs git-rebase to always recreate commits as
 they are being replayed, even if fast-forwards are possible.
 
 However, if git-rebase is asked to recreate merge commits (via the -p
 option), it suddenly ignores the --no-ff option and fast-forwards
 both normal and merge commits whenever possible.
 
 git-rebase--interactive, which is responsible for recreating merge
 commits during a rebase, maintains a variable fast_forward to decide
 whether the current replay should be tried as a fast-forward.
 Previously, fast_forward was on by default and would get toggled only
 if a parent was rewritten or a squash was in effect. Also turn
 fast_forward off if --no-ff is in use, which is signalled by
 git-rebase through the variable force_rebase.
 
 If --no-ff is not in use, try to fast-forward HEAD using git-reset as
 before. In contrast, if --no-ff is in use, replay normal commits
 using git-cherry-pick and merge commits using git-merge. Note that
 git-rebase--interactive already provides this machinery for enabling
 and disabling fast-forwards, controlled by fast_forward being
 assigned either t (for boolean true) or f (for boolean false).
 
 As mentioned above, git-rebase--interactive needs to detect when a
 squash is in effect. If several commits are squashed into one, each
 of them is picked using the git-cherry-pick option -n and they get
 all rewritten to the same commit, the squash commit. Previously,
 fast_forward was assigned f if and only if -n was specified. This no
 longer holds for fast_forward might be turned off due to a use of
 --no-ff. To correctly notice squashes, explicitly check for -n.
 
 Add test.
 
 Signed-off-by: Fabian Ruch baf...@gmail.com
 ---
 Hi,
 
 The code checking force_rebase is copied from pick_one, although
 using a ternary operator to initialise fast_forward might be more
 readable. Moreover, the code snippet used to detect squash mode is
 copied from the f arm of the fast_forward case switch, although the
 code base prefers to spell out test(1).
 
 The test recreates a topic branch that merged a second topic branch.
 Therefore, the test case tests the recreation of both normal and
 merge commits.
 
 Commit b499549 first introduced the --no-ff option to git-rebase and
 since then force_rebase seems to respected only by pick_one but not
 by its sibling pick_one_preserving_merges. I couldn't find a reason
 why. Was pick_one_preserving_merges merely overlooked?
 
 Is it a usability issue that conflicting merges will have to be
 resolved again when being replayed now? The same applies to -p and
 the replay of merges with rewritten parents. Should the possibly
 required resolution be mentioned alongside git-rerere in the
 git-rebase manual page?
 
Fabian
 
  git-rebase--interactive.sh|  3 ++-
  t/t3409-rebase-preserve-merges.sh | 12 
  2 files changed, 14 insertions(+), 1 deletion(-)
 
 diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
 index f267d8b..264a768 100644
 --- a/git-rebase--interactive.sh
 +++ b/git-rebase--interactive.sh
 @@ -266,10 +266,11 @@ pick_one_preserving_merges () {
   ;;
   esac
   sha1=$(git rev-parse $sha1)
 + case $force_rebase in '') ;; ?*) fast_forward=f ;; esac
  
   if test -f $state_dir/current-commit
   then
 - if test $fast_forward = t
 + if [ $1 != -n ]
   then
   while read current_commit
   do
 diff --git a/t/t3409-rebase-preserve-merges.sh 
 b/t/t3409-rebase-preserve-merges.sh
 index 8c251c5..838937b 100755
 --- a/t/t3409-rebase-preserve-merges.sh
 +++ b/t/t3409-rebase-preserve-merges.sh
 @@ -81,6 +81,18 @@ test_expect_success 'setup for merge-preserving rebase' \
   git commit -a -m Modify B2
  '
  
 +test_expect_success '--no-ff records new commits' '
 + (
 + cd clone3 
 + test_when_finished 'cd clone3  git checkout topic' 
 + git checkout -b recreated-topic 
 + # recreate topic with merged topic2 (branching-off point A1)
 + git rebase -p --no-ff HEAD~2 
 + test $(git rev-parse new-topic^) != $(git rev-parse topic^) 
 + test $(git rev-parse new-topic) != $(git rev-parse topic)
 + )
 +'
 +
  test_expect_success '--continue works after a conflict' '
   (
   cd clone2 
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/3] fixup for patch 2: minor style fix

2014-07-16 Thread Matthieu Moy
Signed-off-by: Matthieu Moy matthieu@imag.fr
---
 t/t1308-config-set.sh | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/t/t1308-config-set.sh b/t/t1308-config-set.sh
index 4752fd9..ea031bf 100755
--- a/t/t1308-config-set.sh
+++ b/t/t1308-config-set.sh
@@ -150,8 +150,8 @@ test_expect_success 'find value from a configset' '
 '
 
 test_expect_success 'find value with highest priority from a configset' '
-   echo hask  expect 
-   test-config configset_get_value case.baz config2 .git/config  actual 
+   echo hask expect 
+   test-config configset_get_value case.baz config2 .git/config actual 
test_cmp expect actual
 '
 
@@ -163,7 +163,7 @@ test_expect_success 'find value_list for a key from a 
configset' '
lama
ball
EOF
-   test-config configset_get_value case.baz config2 .git/config  actual 
+   test-config configset_get_value case.baz config2 .git/config actual 
test_cmp expect actual
 '
 
@@ -173,7 +173,7 @@ test_expect_success 'proper error on non-existant files' '
test_cmp expect actual
 '
 
-test_expect_success 'proper error on non-accessible  files' '
+test_expect_success 'proper error on non-accessible files' '
chmod -r .git/config 
test_when_finished chmod +r .git/config 
echo Error reading configuration file .git/config. expect 
@@ -184,14 +184,14 @@ test_expect_success 'proper error on non-accessible  
files' '
 test_expect_success 'proper error on error in default config files' '
cp .git/config .git/config.old 
test_when_finished mv .git/config.old .git/config 
-   echo [  .git/config 
+   echo [ .git/config 
echo fatal: bad config file line 35 in .git/config expect 
test_expect_code 128 test-config get_value foo.bar 2actual 
test_cmp expect actual
 '
 
 test_expect_success 'proper error on error in custom config files' '
-   echo [  syntax-error 
+   echo [ syntax-error 
echo fatal: bad config file line 1 in syntax-error expect 
test_expect_code 128 test-config configset_get_value foo.bar 
syntax-error 2actual 
test_cmp expect actual
-- 
2.0.0.262.gdafc651

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


[PATCH 2/3] fixup for patch 2: actually check the return value

2014-07-16 Thread Matthieu Moy
Signed-off-by: Matthieu Moy matthieu@imag.fr
---
I won't fight for this, but I think it makes sense.

 t/t1308-config-set.sh |  4 ++--
 test-config.c | 10 ++
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/t/t1308-config-set.sh b/t/t1308-config-set.sh
index ea031bf..f0307b7 100755
--- a/t/t1308-config-set.sh
+++ b/t/t1308-config-set.sh
@@ -168,7 +168,7 @@ test_expect_success 'find value_list for a key from a 
configset' '
 '
 
 test_expect_success 'proper error on non-existant files' '
-   echo Error reading configuration file non-existant-file. expect 
+   echo Error (-1) reading configuration file non-existant-file. expect 

test_expect_code 2 test-config configset_get_value foo.bar 
non-existant-file 2actual 
test_cmp expect actual
 '
@@ -176,7 +176,7 @@ test_expect_success 'proper error on non-existant files' '
 test_expect_success 'proper error on non-accessible files' '
chmod -r .git/config 
test_when_finished chmod +r .git/config 
-   echo Error reading configuration file .git/config. expect 
+   echo Error (-1) reading configuration file .git/config. expect 
test_expect_code 2 test-config configset_get_value foo.bar .git/config 
2actual 
test_cmp expect actual
 '
diff --git a/test-config.c b/test-config.c
index cad35f4..9dd1b22 100644
--- a/test-config.c
+++ b/test-config.c
@@ -86,8 +86,9 @@ int main(int argc, char **argv)
}
} else if (!strcmp(argv[1], configset_get_value)) {
for (i = 3; i  argc; i++) {
-   if (git_configset_add_file(cs, argv[i])) {
-   fprintf(stderr, Error reading configuration 
file %s.\n, argv[i]);
+   int err;
+   if ((err = git_configset_add_file(cs, argv[i]))) {
+   fprintf(stderr, Error (%d) reading 
configuration file %s.\n, err, argv[i]);
goto exit2;
}
}
@@ -103,8 +104,9 @@ int main(int argc, char **argv)
}
} else if (!strcmp(argv[1], configset_get_value_multi)) {
for (i = 3; i  argc; i++) {
-   if (git_configset_add_file(cs, argv[i])) {
-   fprintf(stderr, Error reading configuration 
file %s.\n, argv[i]);
+   int err;
+   if ((err = git_configset_add_file(cs, argv[i]))) {
+   fprintf(stderr, Error (%d) reading 
configuration file %s.\n, err, argv[i]);
goto exit2;
}
}
-- 
2.0.0.262.gdafc651

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


[PATCH 3/3] fixup for patch 1: typo

2014-07-16 Thread Matthieu Moy
Signed-off-by: Matthieu Moy matthieu@imag.fr
---
 Documentation/technical/api-config.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/technical/api-config.txt 
b/Documentation/technical/api-config.txt
index fc0e379..8a86e45 100644
--- a/Documentation/technical/api-config.txt
+++ b/Documentation/technical/api-config.txt
@@ -242,7 +242,7 @@ Configset API provides functions for the above mentioned 
work flow, including:
 
Parses the file and adds the variable-value pairs to the `config_set`,
dies if there is an error in parsing the file. Returns 0 on success, or
-   -1 if the file doesnot exist or is inaccessible. The user has to decide
+   -1 if the file does not exist or is inaccessible. The user has to decide
if he wants to free the incomplete configset or continue using it when
the function returns -1.
 
-- 
2.0.0.262.gdafc651

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


Re: [PATCH v9r2 1/2] add `config_set` API for caching config-like files

2014-07-16 Thread Tanay Abhra


On 7/16/2014 9:36 PM, Matthieu Moy wrote:
 Tanay Abhra tanay...@gmail.com writes:
 
 implemented as a thin wrapper around the `config_set` API.

 Signed-off-by: Matthieu Moy matthieu@imag.fr
 Signed-off-by: Tanay Abhra tanay...@gmail.com
  Documentation/technical/api-config.txt | 137 +
  cache.h|  30 
  config.c   | 264 
 +
  3 files changed, 431 insertions(+)
 
 (you broke the patch by removing the ---)


Yikes, sorry about that.

 +static void git_config_check_init(void)
 +{
 +if (the_config_set.hash_initialized)
 +return;
 +git_configset_init(the_config_set);
 +git_config(config_set_callback, the_config_set);
 +}
 
 So, you're now ignoring the return value of git_config. What is the
 rationale for this? In particular, why did you reject the die
 possibility (I understood that you were inclined to take this option, so
 I'm curious why you changed your mind).


The errors (non accessible, non existent files etc) were already being caught by
git_config_early(). Since git_config() only returns positive values except
the weird race case you mentioned, I thought the die confused the reader
of the patch more than it provided error checking. I also tried myself
simulating the race condition but failed. All the callers of git_config()
also ignore the return value, so I ended up ignoring the return value myself.

 OTOH, you're transmitting the return value without dying here:
 
 +int git_configset_add_file(struct config_set *cs, const char *filename)
 +{
 + return git_config_from_file(config_set_callback, filename, cs);
 +}
 
 and I think this one is correct, as we cannot tell in advance how
 serious an error would be for any callers. And we do test this (I think
 we can improve a bit, I'll send a fixup patch).


After reading the commit log that you mentioned and some previous ones before
that I surmised that the official slant was to silently ignore nonexistent
files. Though an access_or_warn() check was placed on most of the files
like git attributes, since non accessible file errors may be a user 
configuration
error. So, I decided to ignore the return value.

But I do think that an access_or_warn() check should be put on git config --file
and git_configset_add_file since other parts of git follow it. What do
you think about it, still I will send followup patch correcting the git config
--file condition where it silently ignores the file access error and continues?


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


Re: [PATCH 2/3] fixup for patch 2: actually check the return value

2014-07-16 Thread Matthieu Moy
Tanay Abhra tanay...@gmail.com writes:

 I think it would be unnecessary for the current iteration.
 Currently git_configset_add_file has only two possible return values
 -1 or 0.

Yes. My point is just to check that statement in tests. (I'm usually
wary of statements like is obviously true so I don't need to test
it ;-) )

 I could add specialized error values for ENOENT or ENOTDIR or EACCES,
 but the logs show that we silently ignore the first two. I can add an
 access warn for the third. What do you think?

I think the code is fine as it is.

But anyway, it's not terribly important.

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v8 4/4] cache-tree: Write updated cache-tree after commit

2014-07-16 Thread Junio C Hamano
Duy Nguyen pclo...@gmail.com writes:

   If you do not
 use the extra temporary file, you start from index.lock left by
 add -i, write the updated index into index.lock and if you fail
 to write, you have to roll back the entire index---you lose the
 option to use the index left by add -i without repopulated
 cache-tree.  But in the index update context, I do not think such a
 complexity is not necessary.  If something fails, we should fail and
 roll back the entire index.

 I probably look at the problem from a wrong angle. To me the result of
 commit -p is precious. I'm not a big user of commit -p myself as I
 prefer add -p but it's the same...

Oh, we agree that the result of commit -p is precious.

But the point of David's series is to change the definition of the
precious result to not just commit is made as asked, but now
also to include that the index the user will use for continued work
will have populated cache-tree.  The series thinks both are precious.

As you can probably read from my review responses, I am not sold to
the idea that spending extra cycles to pre-populate cache-tree is
100% good idea, but if we _were_ to accept that it is a good idea,
it logically follows that failing to populate cache-tree is just as
a failure as failing to commit.

In any case, it is unlikely for writing out the updated index with
refreshed cache-tree to fail and blow away the partially built index
(we do not even attempt to reopen/update if we cannot prepare
in-core cache-tree), so I do not think it is such a big deal either
way.



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


Re: [PATCH 1/2] MinGW: fix compile error due to missing ELOOP

2014-07-16 Thread Junio C Hamano
Karsten Blees karsten.bl...@gmail.com writes:

 MinGW and MSVC before 2010 don't define ELOOP, use EMLINK (aka Too many
 links) instead.

 Signed-off-by: Karsten Blees bl...@dcon.de
 ---

Thanks; will apply directly to 'master'.

  compat/mingw.h | 3 +++
  1 file changed, 3 insertions(+)

 diff --git a/compat/mingw.h b/compat/mingw.h
 index 405c08f..510530c 100644
 --- a/compat/mingw.h
 +++ b/compat/mingw.h
 @@ -35,6 +35,9 @@ typedef int socklen_t;
  #ifndef EWOULDBLOCK
  #define EWOULDBLOCK EAGAIN
  #endif
 +#ifndef ELOOP
 +#define ELOOP EMLINK
 +#endif
  #define SHUT_WR SD_SEND
  
  #define SIGHUP 1
 -- 
 2.0.1.779.g26aeac4.dirty

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


Re: [PATCH v9 4/4] tag: support configuring --sort via .gitconfig

2014-07-16 Thread Junio C Hamano
Keller, Jacob E jacob.e.kel...@intel.com writes:

 On Tue, 2014-07-15 at 19:42 -0400, Jeff King wrote:
 On Tue, Jul 15, 2014 at 04:32:59PM -0700, Jacob Keller wrote:
 
  +static void error_bad_sort_config(const char *err, va_list params)
  +{
  +  vreportf(warning: tag.sort has , err, params);
  +}
 
 This feels a little like an abuse of the prefix field of vreportf, but
 as you probably saw in my for fun patch, doing it right means
 formatting into a buffer and then reformatting that (which we're
 already doing again in vreportf, but less flexibly). I dunno.
 
 At any rate, this should be marked for translation, no?
 
 -Peff

 Oh, yes it probably should. It's definitely a little bit abusive of the
 prefix field, but that seemed easier.

And i18n would automatically mean this will not work, no?  There is
no guarantee that the translation of warning:  will be followed
directly by the translation of tag.sort has without any words from
variable part in all languages.

After all, it seems to me that the one in

http://thread.gmane.org/gmane.comp.version-control.git/253346

struck the right balance among various abuses; let's use the error
reporter from that version, instead of going down this rabbit hole.

Thanks.



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


Re: [PATCH v1] rebase -p: Command line option --no-ff is ignored

2014-07-16 Thread Marc Branchaud
On 14-07-16 12:01 PM, Fabian Ruch wrote:
 Hi Marc,
 
 I forgot to cc your mailbox when I posted this patch last week. Do you
 still remember whether there was a particular reason why
 pick_one_preserving_merges wasn't touched by the commit b499549 (Teach
 rebase the --no-ff option.), by any chance?

I think it was simply overlooked.  (Though it was very long ago and my brain
can barely keep track of what I did last week...)

M.

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


Re: [PATCH v20 40/48] refs.c: add an err argument to delete_ref_loose

2014-07-16 Thread Ronnie Sahlberg
On Tue, Jul 8, 2014 at 7:19 AM, Michael Haggerty mhag...@alum.mit.edu wrote:
 On 06/20/2014 04:43 PM, Ronnie Sahlberg wrote:
 Add an err argument to delete_loose_ref so that we can pass a descriptive
 error string back to the caller. Pass the err argument from transaction
 commit to this function so that transaction users will have a nice error
 string if the transaction failed due to delete_loose_ref.

 Add a new function unlink_or_err that we can call from delete_ref_loose. This
 function is similar to unlink_or_warn except that we can pass it an err
 argument. If err is non-NULL the function will populate err instead of
 printing a warning().

 Simplify warn_if_unremovable.

 The change to warn_if_unremovable() is orthogonal to the rest of the
 commit and should be a separate commit.

Done.
I split it into three patches.
One patch for the warn_if_removable change
another patch to add unlink_or_msg to wrapper.c
and a final patch to change delete_loose_ref.


 Signed-off-by: Ronnie Sahlberg sahlb...@google.com
 ---
  refs.c| 33 -
  wrapper.c | 14 ++
  2 files changed, 34 insertions(+), 13 deletions(-)

 diff --git a/refs.c b/refs.c
 index 92a06d4..c7d1f3e 100644
 --- a/refs.c
 +++ b/refs.c
 @@ -2544,16 +2544,38 @@ int repack_without_refs(const char **refnames, int 
 n, struct strbuf *err)
   return ret;
  }

 -static int delete_ref_loose(struct ref_lock *lock, int flag)
 +static int add_err_if_unremovable(const char *op, const char *file,
 +   struct strbuf *e, int rc)

 This function is only used once.  Given also that its purpose is not
 that obvious from its signature, it seems to me that the code would be
 easier to read if it were inlined.

 +{
 + int err = errno;
 + if (rc  0  errno != ENOENT) {
 + strbuf_addf(e, unable to %s %s: %s,
 + op, file, strerror(errno));
 + errno = err;
 + return -1;
 + }
 + return 0;
 +}
 +
 +static int unlink_or_err(const char *file, struct strbuf *err)

 The name of this function is misleading; it sounds like it will try to
 unlink the file and if not possible call error().  Maybe a name like
 unlink_or_report would be less prejudicial.

 It might also make sense to move this function to wrapper.c and
 implement unlink_or_warn() in terms of it rather than vice versa.

 +{
 + if (err)
 + return add_err_if_unremovable(unlink, file, err,
 +   unlink(file));
 + else
 + return unlink_or_warn(file);
 +}
 +
 +static int delete_ref_loose(struct ref_lock *lock, int flag, struct strbuf 
 *err)
  {
   if (!(flag  REF_ISPACKED) || flag  REF_ISSYMREF) {
   /* loose */
 - int err, i = strlen(lock-lk-filename) - 5; /* .lock */
 + int res, i = strlen(lock-lk-filename) - 5; /* .lock */

   lock-lk-filename[i] = 0;
 - err = unlink_or_warn(lock-lk-filename);
 + res = unlink_or_err(lock-lk-filename, err);
   lock-lk-filename[i] = '.';
 - if (err  errno != ENOENT)
 + if (res)
   return 1;
   }
   return 0;
 @@ -3603,7 +3625,8 @@ int ref_transaction_commit(struct ref_transaction 
 *transaction,
   struct ref_update *update = updates[i];

   if (update-lock) {
 - ret |= delete_ref_loose(update-lock, update-type);
 + ret |= delete_ref_loose(update-lock, update-type,
 + err);
   if (!(update-flags  REF_ISPRUNING))
   delnames[delnum++] = update-lock-ref_name;
   }
 diff --git a/wrapper.c b/wrapper.c
 index bc1bfb8..740e193 100644
 --- a/wrapper.c
 +++ b/wrapper.c
 @@ -429,14 +429,12 @@ int xmkstemp_mode(char *template, int mode)

  static int warn_if_unremovable(const char *op, const char *file, int rc)
  {
 - if (rc  0) {
 - int err = errno;
 - if (ENOENT != err) {
 - warning(unable to %s %s: %s,
 - op, file, strerror(errno));
 - errno = err;
 - }
 - }
 + int err;
 + if (rc = 0 || errno == ENOENT)
 + return rc;
 + err = errno;
 + warning(unable to %s %s: %s, op, file, strerror(errno));
 + errno = err;
   return rc;
  }



 Michael

 --
 Michael Haggerty
 mhag...@alum.mit.edu

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


[PATCH v2 1/2] rebase--am: use --cherry-pick instead of --ignore-if-in-upstream

2014-07-16 Thread John Keeping
When using `git format-patch --ignore-if-in-upstream` we are only
allowed to give a single revision range.  In the next commit we will
want to add an additional exclusion revision in order to handle fork
points correctly, so convert `git-rebase--am` to use a symmetric
difference with `--cherry-pick --right-only`.

This does not change the result of the format-patch invocation, just how
we spell the arguments.

Signed-off-by: John Keeping j...@keeping.me.uk
---

Unchanged from v1.

 git-rebase--am.sh | 15 +++
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/git-rebase--am.sh b/git-rebase--am.sh
index ca20e1e..902bf2d 100644
--- a/git-rebase--am.sh
+++ b/git-rebase--am.sh
@@ -29,7 +29,13 @@ skip)
;;
 esac
 
-test -n $rebase_root  root_flag=--root
+if test -z $rebase_root
+   # this is now equivalent to ! -z $upstream
+then
+   revisions=$upstream...$orig_head
+else
+   revisions=$onto...$orig_head
+fi
 
 ret=0
 if test -n $keep_empty
@@ -38,14 +44,15 @@ then
# empty commits and even if it didn't the format doesn't really lend
# itself well to recording empty patches.  fortunately, cherry-pick
# makes this easy
-   git cherry-pick ${gpg_sign_opt:+$gpg_sign_opt} --allow-empty 
$revisions
+   git cherry-pick ${gpg_sign_opt:+$gpg_sign_opt} --allow-empty \
+   --right-only $revisions
ret=$?
 else
rm -f $GIT_DIR/rebased-patches
 
-   git format-patch -k --stdout --full-index --ignore-if-in-upstream \
+   git format-patch -k --stdout --full-index --cherry-pick --right-only \
--src-prefix=a/ --dst-prefix=b/ --no-renames --no-cover-letter \
-   $root_flag $revisions $GIT_DIR/rebased-patches
+   $revisions $GIT_DIR/rebased-patches
ret=$?
 
if test 0 != $ret
-- 
2.0.1.472.g6f92e5f.dirty

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


[PATCH v1] rebase --root: sentinel commit cloaks empty commits

2014-07-16 Thread Fabian Ruch
git-rebase supports the option `--root` both with and without
`--onto`. In rebase root mode it replays all commits reachable from a
branch on top of another branch, including the very first commit. In
case `--onto` is not specified, that other branch is temporarily
provided by creating an empty commit. When the first commit on the
to-do list is being replayed, the so-called sentinel commit is
amended using the log message and patch of the replayed commit. Since
the sentinel commit is empty, this results in a replacement of the
sentinel commit with the new root commit of the rebased branch.

The combination of `--root` and no `--onto` implies an interactive
rebase. When `--preserve-merges` is not specified on the command
line, git-rebase--interactive uses `--cherry-pick` with git-rev-list
to put the initial to-do list together. The left side is given by the
fake base and the right side by the branch being rebased. What
happens now is that any empty commit on the original branch is
treated as a cherry-pick of the sentinel commit and subsequently
omitted from the to-do list. This is a bug if `--keep-empty` is
specified also.

Even without `--keep-empty`, using the sentinel commit as left side
with git-rev-list can result in a faulty rebased branch. Indeed, in
the unlikely case that the original branch consists solely of empty
commits, the bug crops up in the strangest fashion as all commits are
skipped and the sentinel commit is not replaced. As a result,
git-rebase produces a branch with a single empty commit.

To trigger the replacement of the sentinel commit, git-rebase assigns
the variable `squash_onto`. Special case a second time regarding
`squash_onto` and run git-rev-list without a left side if the
variable is assigned. The latter is the case if and only if `--root`
is used without `--onto`, that is `upstream` points to the sentinel
commit and `$upstream...$orig_head` would subtract a commit that is
not actually there from the original branch.

Fix a typo in `is_empty_commit`. It always found root commits
non-empty so that empty root commits were scheduled even without
`--keep-empty`. The POSIX specification states that command
substitutions are to be executed in sub-shells, which makes exit(1)
and variable assignments not affect the script execution state. That
was the reason why `ptree` was null for parentless commits and the
test `$tree = $ptree` always false for them.

Add tests.

Signed-off-by: Fabian Ruch baf...@gmail.com
---
Hi,

Three test cases were added to the bug report to account for the
additional cases in which the bug strikes (raised by Michael on the
other sub-thread). A bugfix is included now as well.

Concerning the bugfix: Obviously, the patch misuses the `squash_onto`
flag because it assumes that the new base is empty except for the
sentinel commit. The variable name does not imply anything close to
that. An additional flag to disable the use of the git-rev-list
option `--cherry-pick` would work and make sense again (for instance,
`keep_redundant`). However, the following two bugs, not related to
empty commits, seem to suggest that git-rebase--interactive cannot
work obliviously to non-existent bases.

 1) git-rebase--interactive when used with `--root` and the to-do
list `noop` results in the original branch's history being
rewritten to contain only the sentinel commit.

git-rebase--interactive correctly checkouts `$onto` and replays
no commits on top of it but git-rebase has forgotten that `$onto`
was fake.

 2) git-rebase--interactive when used with `--root` always creates a
fresh root commit, regardless of `--no-ff` being specified.

With the current meaning of `squash_onto`,
git-rebase--interactive cannot just reset the branch to the old
root commit. It is really the fault of git-rebase to start off
with a new commit.

Please take a closer look at the last two test cases that specify the
expected behaviour of rebasing a branch that tracks the empty tree.
At this point they expect the Nothing to do error (aborts with
untouched history). This is consistent with rebasing only empty
commits without `--root`, which also doesn't just delete them from
the history. Furthermore, I think the two alternatives adding a note
that all commits in the range were empty, and removing the empty
commits (thus making the branch empty) are better discussed in a
separate bug report.

Thanks for your time,
   Fabian

 git-rebase--interactive.sh | 20 ++-
 t/t3412-rebase-root.sh | 49 ++
 2 files changed, 64 insertions(+), 5 deletions(-)

diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index f267d8b..71ca0f0 100644
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -201,10 +201,10 @@ has_action () {
 }
 
 is_empty_commit() {
-   tree=$(git rev-parse -q --verify $1^{tree} 2/dev/null ||
-   die $1: not a commit that can be picked)
-   

Re: [PATCH v8 1/4] usage: make error functions a stack

2014-07-16 Thread Keller, Jacob E
There was no way to get the current error routine now, and I figured
that a stack was a simple way of saving the old routine.

Essentially these two paths would be the same as a save/restore except
we manage it via a stack. I don't really see how that would end up any
different. I mean I don't mind either approach.

Thanks,
Jake

On Tue, 2014-07-15 at 17:49 -0700, Junio C Hamano wrote:
 I actually am not a big fan of stack for a thing like this, to be honest.
 Wouldn't it be sufficient for the callers who want specific behaviour from
 its callees to
 
  - save away the current error/warning routines;
  - set error/warning routines to its own custom versions;
  - call the callees;
  - set error/warning routines back to their original; and
  - return from it
 
 at least in the code paths under discussion?
 
 
 On Tue, Jul 15, 2014 at 4:26 PM, Keller, Jacob E
 jacob.e.kel...@intel.com wrote:
  On Tue, 2014-07-15 at 15:47 -0700, Junio C Hamano wrote:
  Jacob Keller jacob.e.kel...@intel.com writes:
 
extern void set_error_routine(void (*routine)(const char *err, va_list 
   params));
   +extern void pop_error_routine(void);
 
  pop that undoes set smells somewhat weird.  Perhaps we should rename
  set to push?  That would allow us catch possible topics that add new
  calls to set_error_routine() as well by forcing the system not to
  link when they are merged without necessary fixes.
 
 
  Also curious what your thoughts on making every set_*_routine to be a
  stack? For now I was only planning on error but it maybe makes sense to
  change them all?
 
  Thanks,
  Jake
 




Re: [PATCH v9 4/4] tag: support configuring --sort via .gitconfig

2014-07-16 Thread Keller, Jacob E
On Wed, 2014-07-16 at 10:59 -0700, Junio C Hamano wrote:
 Keller, Jacob E jacob.e.kel...@intel.com writes:
 
  On Tue, 2014-07-15 at 19:42 -0400, Jeff King wrote:
  On Tue, Jul 15, 2014 at 04:32:59PM -0700, Jacob Keller wrote:
  
   +static void error_bad_sort_config(const char *err, va_list params)
   +{
   +vreportf(warning: tag.sort has , err, params);
   +}
  
  This feels a little like an abuse of the prefix field of vreportf, but
  as you probably saw in my for fun patch, doing it right means
  formatting into a buffer and then reformatting that (which we're
  already doing again in vreportf, but less flexibly). I dunno.
  
  At any rate, this should be marked for translation, no?
  
  -Peff
 
  Oh, yes it probably should. It's definitely a little bit abusive of the
  prefix field, but that seemed easier.
 
 And i18n would automatically mean this will not work, no?  There is
 no guarantee that the translation of warning:  will be followed
 directly by the translation of tag.sort has without any words from
 variable part in all languages.
 
 After all, it seems to me that the one in
 
 http://thread.gmane.org/gmane.comp.version-control.git/253346
 
 struck the right balance among various abuses; let's use the error
 reporter from that version, instead of going down this rabbit hole.
 
 Thanks.
 
 
 

This is fine with me :)

Thanks,
Jake


Re: [PATCH v2 2/2] rebase: omit patch-identical commits with --fork-point

2014-07-16 Thread Junio C Hamano
John Keeping j...@keeping.me.uk writes:

 When the `--fork-point` argument was added to `git rebase`, we changed
 the value of $upstream to be the fork point instead of the point from
 which we want to rebase.  When $orig_head..$upstream is empty this does
 not change the behaviour, but when there are new changes in the upstream
 we are no longer checking if any of them are patch-identical with
 changes in $upstream..$orig_head.

 Fix this by introducing a new variable to hold the fork point and using
 this to restrict the range as an extra (negative) revision argument so
 that the set of desired revisions becomes (in fork-point mode):

   git rev-list --cherry-pick --right-only \
   $upstream...$orig_head ^$fork_point

 This allows us to correctly handle the scenario where we have the
 following topology:

   C --- D --- E  - dev
  /
 B  - master@{1}
/
   o --- B' --- C* --- D*  - master

 where:
 - B' is a fixed-up version of B that is not patch-identical with B;
 - C* and D* are patch-identical to C and D respectively and conflict
   textually if applied in the wrong order;
 - E depends textually on D.

 The correct result of `git rebase master dev` is that B is identified as
 the fork-point of dev and master, so that C, D, E are the commits that
 need to be replayed onto master; but C and D are patch-identical with C*
 and D* and so can be dropped, so that the end result is:

   o --- B' --- C* --- D* --- E  - dev

 If the fork-point is not identified, then picking B onto a branch
 containing B' results in a conflict and if the patch-identical commits
 are not correctly identified then picking C onto a branch containing D
 (or equivalently D*) results in a conflict.

 This change allows us to handle both of these cases, where previously we
 either identified the fork-point (with `--fork-point`) but not the
 patch-identical commits *or* (with `--no-fork-point`) identified the
 patch-identical commits but not the fact that master had been rewritten.

 Reported-by: Ted Felix t...@tedfelix.com
 Signed-off-by: John Keeping j...@keeping.me.uk
 ---

 Change from v1:
 - add a test case

 diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh
 index 80e0a95..47b5682 100755
 --- a/t/t3400-rebase.sh
 +++ b/t/t3400-rebase.sh
 @@ -169,6 +169,29 @@ test_expect_success 'default to common base in 
 @{upstream}s reflog if no upstrea
   test_cmp expect actual
  '
  
 +test_expect_success 'cherry-picked commits and fork-point work together' '
 + git checkout default-base 
 + echo Amended A 
 + git commit -a --no-edit --amend 
 + test_commit B B 
 + test_commit new_B B New B 
 + test_commit C C 
 + git checkout default 
 + git reset --hard default-base@{4} 
 + test_commit D D 
 + git cherry-pick -2 default-base^ 
 + test_commit final_B B Final B 
 + git rebase 

mental note: this rebases default (i.e. the current branch) on
default-base; it depends on branch.default.{remote,merge} being set
by the previous test piece.

 + echo Amended expect 
 + test_cmp A expect 
 + echo Final B expect 
 + test_cmp B expect 
 + echo C expect 
 + test_cmp C expect 
 + echo D expect 
 + test_cmp D expect
 +'

Thanks.  Do these labels on the commits have any relation to the
topology illustrated in the log message?

It looks like the above produces this:

  a'---D---B'--new_B'---final_B (default)
 /
oa---B---new_B---C (default-base)
  \
   D''---final_B''

where 'a' is Modify A. from the original set-up and B and new_B
are the cherry-picks to be filtered out during the rebase.  Am I
reading the test correctly?

  test_expect_success 'rebase -q is quiet' '
   git checkout -b quiet topic 
   git rebase -q master output.out 21 
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v9 4/4] tag: support configuring --sort via .gitconfig

2014-07-16 Thread Keller, Jacob E
On Wed, 2014-07-16 at 10:59 -0700, Junio C Hamano wrote:
 Keller, Jacob E jacob.e.kel...@intel.com writes:
 
  On Tue, 2014-07-15 at 19:42 -0400, Jeff King wrote:
  On Tue, Jul 15, 2014 at 04:32:59PM -0700, Jacob Keller wrote:
  
   +static void error_bad_sort_config(const char *err, va_list params)
   +{
   +vreportf(warning: tag.sort has , err, params);
   +}
  
  This feels a little like an abuse of the prefix field of vreportf, but
  as you probably saw in my for fun patch, doing it right means
  formatting into a buffer and then reformatting that (which we're
  already doing again in vreportf, but less flexibly). I dunno.
  
  At any rate, this should be marked for translation, no?
  
  -Peff
 
  Oh, yes it probably should. It's definitely a little bit abusive of the
  prefix field, but that seemed easier.
 
 And i18n would automatically mean this will not work, no?  There is
 no guarantee that the translation of warning:  will be followed
 directly by the translation of tag.sort has without any words from
 variable part in all languages.
 
 After all, it seems to me that the one in
 
 http://thread.gmane.org/gmane.comp.version-control.git/253346
 
 struck the right balance among various abuses; let's use the error
 reporter from that version, instead of going down this rabbit hole.
 
 Thanks.
 
 
 

So is that patch series version acceptable then? Or should I spin one
again that is in that vein?

Thanks,
Jake


Re: [PATCH v9 4/4] tag: support configuring --sort via .gitconfig

2014-07-16 Thread Junio C Hamano
Keller, Jacob E jacob.e.kel...@intel.com writes:

 After all, it seems to me that the one in
 
 http://thread.gmane.org/gmane.comp.version-control.git/253346
 
 struck the right balance among various abuses; let's use the error
 reporter from that version, instead of going down this rabbit hole.
 
 Thanks.

 So is that patch series version acceptable then? Or should I spin one
 again that is in that vein?

I do not offhand know what other changes you had in v9 since
$gmane/253346, so I'll leave it up to you.  If the only difference
is the error reporting codepath, and you are happy with what I have
in my tree

$ git log -p --reverse -3 a93d886b9

then we can proceed with that version.  Have there been any issues
raised on that older version other than error reporting?




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


Re: [PATCH v2 2/2] rebase: omit patch-identical commits with --fork-point

2014-07-16 Thread Ted Felix

On 07/16/2014 03:23 PM, John Keeping wrote:

Change from v1:
 - add a test case


Test case is working fine for me.  It passes with the patch and fails 
without.  However, it does seem to cause all the rest of the test cases 
to fail if it fails.  Is there some cleanup missing?


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


Re: [PATCH v9 4/4] tag: support configuring --sort via .gitconfig

2014-07-16 Thread Keller, Jacob E
On Wed, 2014-07-16 at 14:40 -0700, Junio C Hamano wrote:
 Keller, Jacob E jacob.e.kel...@intel.com writes:
 
  After all, it seems to me that the one in
  
  http://thread.gmane.org/gmane.comp.version-control.git/253346
  
  struck the right balance among various abuses; let's use the error
  reporter from that version, instead of going down this rabbit hole.
  
  Thanks.
 
  So is that patch series version acceptable then? Or should I spin one
  again that is in that vein?
 
 I do not offhand know what other changes you had in v9 since
 $gmane/253346, so I'll leave it up to you.  If the only difference
 is the error reporting codepath, and you are happy with what I have
 in my tree
 
 $ git log -p --reverse -3 a93d886b9
 
 then we can proceed with that version.  Have there been any issues
 raised on that older version other than error reporting?
 
 
 
 

I'll double check.

Thanks,
Jake


[PATCH v10] tag: support configuring --sort via .gitconfig

2014-07-16 Thread Jacob Keller
Add support for configuring default sort ordering for git tags. Command
line option will override this configured value, using the exact same
syntax.

Cc: Jeff King p...@peff.net
Signed-off-by: Jacob Keller jacob.e.kel...@intel.com
Signed-off-by: Junio C Hamano gits...@pobox.com
---
Based on what's in Junio's tree, this patch includes some minor changes to fix
up other non-error reporting changes included in previous versions. The other
patches in his tree already match so we can leave them as they are.

 Documentation/config.txt  |  5  
 Documentation/git-tag.txt |  5 +++-
 builtin/tag.c | 68 ++-
 t/t7004-tag.sh| 36 +
 4 files changed, 95 insertions(+), 19 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 9f467d3820a4..9d4f249606b3 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -2351,6 +2351,11 @@ submodule.name.ignore::
--ignore-submodules option. The 'git submodule' commands are not
affected by this setting.
 
+tag.sort::
+   This variable controls the sort ordering of tags when displayed by
+   linkgit:git-tag[1]. Without the --sort=value option provided, the
+   value of this variable will be used as the default.
+
 tar.umask::
This variable can be used to restrict the permission bits of
tar archive entries.  The default is 0002, which turns off the
diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt
index b424a1bc48bb..320908369f06 100644
--- a/Documentation/git-tag.txt
+++ b/Documentation/git-tag.txt
@@ -99,7 +99,9 @@ OPTIONS
Sort in a specific order. Supported type is refname
(lexicographic order), version:refname or v:refname (tag
names are treated as versions). Prepend - to reverse sort
-   order.
+   order. When this option is not given, the sort order defaults to the
+   value configured for the 'tag.sort' variable if it exists, or
+   lexicographic order otherwise. See linkgit:git-config[1].
 
 --column[=options]::
 --no-column::
@@ -317,6 +319,7 @@ include::date-formats.txt[]
 SEE ALSO
 
 linkgit:git-check-ref-format[1].
+linkgit:git-config[1].
 
 GIT
 ---
diff --git a/builtin/tag.c b/builtin/tag.c
index 1101c19596c5..e063035515d9 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -32,6 +32,8 @@ static const char * const git_tag_usage[] = {
 #define SORT_MASK   0x7fff
 #define REVERSE_SORT0x8000
 
+static int tag_sort;
+
 struct tag_filter {
const char **patterns;
int lines;
@@ -346,9 +348,51 @@ static const char tag_template_nocleanup[] =
Lines starting with '%c' will be kept; you may remove them
 yourself if you want to.\n);
 
+/*
+ * Parse a sort string, and return 0 if parsed successfully. Will return
+ * non-zero when the sort string does not parse into a known type. If var is
+ * given, the error message becomes a warning and includes information about
+ * the configuration value.
+ */
+static int parse_sort_string(const char *var, const char *arg, int *sort)
+{
+   int type = 0, flags = 0;
+
+   if (skip_prefix(arg, -, arg))
+   flags |= REVERSE_SORT;
+
+   if (skip_prefix(arg, version:, arg) || skip_prefix(arg, v:, arg))
+   type = VERCMP_SORT;
+   else
+   type = STRCMP_SORT;
+
+   if (strcmp(arg, refname)) {
+   if (!var)
+   return error(_(unsupported sort specification '%s'), 
arg);
+   else {
+   warning(_(unsupported sort specification '%s' in 
variable '%s'),
+   var, arg);
+   return -1;
+   }
+   }
+
+   *sort = (type | flags);
+
+   return 0;
+}
+
 static int git_tag_config(const char *var, const char *value, void *cb)
 {
-   int status = git_gpg_config(var, value, cb);
+   int status;
+
+   if (!strcmp(var, tag.sort)) {
+   if (!value)
+   return config_error_nonbool(var);
+   parse_sort_string(var, value, tag_sort);
+   return 0;
+   }
+
+   status = git_gpg_config(var, value, cb);
if (status)
return status;
if (starts_with(var, column.))
@@ -522,20 +566,8 @@ static int parse_opt_points_at(const struct option *opt 
__attribute__((unused)),
 static int parse_opt_sort(const struct option *opt, const char *arg, int unset)
 {
int *sort = opt-value;
-   int flags = 0;
 
-   if (skip_prefix(arg, -, arg))
-   flags |= REVERSE_SORT;
-
-   if (skip_prefix(arg, version:, arg) || skip_prefix(arg, v:, arg))
-   *sort = VERCMP_SORT;
-   else
-   *sort = STRCMP_SORT;
-
-   if (strcmp(arg, refname))
-   die(_(unsupported sort specification %s), arg);
-   *sort |= flags;
-   return 0;
+   return 

[PATCH] run-command: use internal argv_array of struct child_process in run_hook_ve()

2014-07-16 Thread René Scharfe
Use the existing argv_array member instead of providing our own.  This
way we don't have to initialize or clean it up explicitly.

Signed-off-by: Rene Scharfe l@web.de
---
 run-command.c | 15 ---
 1 file changed, 4 insertions(+), 11 deletions(-)

diff --git a/run-command.c b/run-command.c
index be07d4a..576dfea 100644
--- a/run-command.c
+++ b/run-command.c
@@ -770,28 +770,21 @@ char *find_hook(const char *name)
 int run_hook_ve(const char *const *env, const char *name, va_list args)
 {
struct child_process hook;
-   struct argv_array argv = ARGV_ARRAY_INIT;
const char *p;
-   int ret;
 
p = find_hook(name);
if (!p)
return 0;
 
-   argv_array_push(argv, p);
-
-   while ((p = va_arg(args, const char *)))
-   argv_array_push(argv, p);
-
memset(hook, 0, sizeof(hook));
-   hook.argv = argv.argv;
+   argv_array_push(hook.args, p);
+   while ((p = va_arg(args, const char *)))
+   argv_array_push(hook.args, p);
hook.env = env;
hook.no_stdin = 1;
hook.stdout_to_stderr = 1;
 
-   ret = run_command(hook);
-   argv_array_clear(argv);
-   return ret;
+   return run_command(hook);
 }
 
 int run_hook_le(const char *const *env, const char *name, ...)
-- 
2.0.0

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


What's cooking in git.git (Jul 2014, #03; Wed, 16)

2014-07-16 Thread Junio C Hamano
Here are the topics that have been cooking.  Commits prefixed with
'-' are only in 'pu' (proposed updates) while commits prefixed with
'+' are in 'next'.

We would need to start slowing down to prepare for -rc0 preview at
the end of this week and then feature freeze.  Some topics that
joined 'next' late may want to stay there for the remainder of this
cycle.  Many of the accumulated fixes have been flushed to 'maint'
and Git 2.0.2 has been tagged.

You can find the changes described here in the integration branches
of the repositories listed at

http://git-blame.blogspot.com/p/git-public-repositories.html

--
[New Topics]

* ek/alt-odb-entry-fix (2014-07-15) 1 commit
 - sha1_file: do not add own object directory as alternate

 Will merge to 'next'.


* jk/rebase-am-fork-point (2014-07-16) 2 commits
 - rebase: omit patch-identical commits with --fork-point
 - rebase--am: use --cherry-pick instead of --ignore-if-in-upstream

 Will merge to 'next'.


* jk/stable-prio-queue (2014-07-15) 4 commits
 - t5539: update a flaky test
 - paint_down_to_common: use prio_queue
 - prio-queue: make output stable with respect to insertion
 - prio-queue: factor out compare and swap operations


* jk/tag-sort (2014-07-13) 2 commits
 - tag: support configuring --sort via .gitconfig
 - tag: fix --sort tests to use cat-\EOF format

 v10 ($gmane/253695) needs to be picked up and replace these.


* nd/path-max-must-go (2014-07-14) 3 commits
  (merged to 'next' on 2014-07-15 at ce68dde)
 + prep_exclude: remove the artificial PATH_MAX limit
 + dir.h: move struct exclude declaration to top level
 + dir.c: coding style fix

 Will merge to 'master'.


* sk/mingw-uni-fix (2014-07-15) 3 commits
 - tests: do not pass iso8859-1 encoded parameter
 - Win32: Unicode file name support (dirent)
 - Win32: Unicode file name support (except dirent)

 Will merge to 'next'.


* ta/config-set (2014-07-15) 2 commits
 - test-config: add tests for the config_set API
 - add `config_set` API for caching config-like files

 Still being discussed.


* kb/avoid-fchmod-for-now (2014-07-16) 1 commit
 - config: use chmod() instead of fchmod()

 Replaces the only two uses of fchmod() with chmod() because the
 former does not work on Windows port and because luckily we can.


* rs/ref-transaction-1 (2014-07-16) 20 commits
 - refs.c: make delete_ref use a transaction
 - refs.c: make prune_ref use a transaction to delete the ref
 - refs.c: remove lock_ref_sha1
 - refs.c: remove the update_ref_write function
 - refs.c: remove the update_ref_lock function
 - refs.c: make lock_ref_sha1 static
 - walker.c: use ref transaction for ref updates
 - fast-import.c: use a ref transaction when dumping tags
 - receive-pack.c: use a reference transaction for updating the refs
 - refs.c: change update_ref to use a transaction
 - branch.c: use ref transaction for all ref updates
 - fast-import.c: change update_branch to use ref transactions
 - sequencer.c: use ref transactions for all ref updates
 - commit.c: use ref transactions for updates
 - replace.c: use the ref transaction functions for updates
 - tag.c: use ref transactions when doing updates
 - refs.c: add transaction.status and track OPEN/CLOSED/ERROR
 - refs.c: make ref_transaction_begin take an err argument
 - refs.c: update ref_transaction_delete to check for error and return status
 - refs.c: change ref_transaction_create to do error checking and return status
 (this branch is used by rs/ref-transaction; uses rs/ref-transaction-0.)

 The second batch of the transactional ref update series.


* rs/unify-is-branch (2014-07-16) 1 commit
 - refs.c: add a public is_branch function

 Will merge to 'next'.

--
[Graduated to master]

* ah/fix-http-push (2014-07-13) 1 commit
  (merged to 'next' on 2014-07-14 at 5d06516)
 + http-push.c: make CURLOPT_IOCTLDATA a usable pointer

 An ancient rewrite passed a wrong pointer to a curl library
 function in a rarely used code path.


* cb/filter-branch-prune-empty-degenerate-merges (2014-07-01) 1 commit
  (merged to 'next' on 2014-07-10 at 860cfea)
 + filter-branch: eliminate duplicate mapped parents

 filter-branch left an empty single-parent commit that results when
 all parents of a merge commit gets mapped to the same commit, even
 under --prune-empty.


* cc/replace-edit (2014-06-25) 3 commits
  (merged to 'next' on 2014-07-10 at 097cd5e)
 + replace: use argv_array in export_object
 + avoid double close of descriptors handed to run_command
 + replace: replace spaces with tabs in indentation
 (this branch is used by jk/replace-edit-raw.)

 Teach git replace an --edit mode.


* ep/submodule-code-cleanup (2014-06-30) 1 commit
  (merged to 'next' on 2014-07-10 at d4de30a)
 + submodule.c: use the ARRAY_SIZE macro


* jk/replace-edit-raw (2014-06-25) 1 commit
  (merged to 'next' on 2014-07-10 at b934bb0)
 + replace: add a --raw mode for --edit
 (this branch uses cc/replace-edit.)

 Teach 

[ANNOUNCE] Git v2.0.2

2014-07-16 Thread Junio C Hamano
The latest maintenance release Git v2.0.2 is now available at
the usual places.

The tarballs are found at:

https://www.kernel.org/pub/software/scm/git/

The following public repositories all have a copy of the 'v2.0.2'
tag and the 'maint' branch that the tag points at:

  url = https://kernel.googlesource.com/pub/scm/git/git
  url = git://repo.or.cz/alt-git.git
  url = https://code.google.com/p/git-core/
  url = git://git.sourceforge.jp/gitroot/git-core/git.git
  url = git://git-core.git.sourceforge.net/gitroot/git-core/git-core
  url = https://github.com/gitster/git

Git v2.0.2 Release Notes


 * Documentation for git submodule sync forgot to say that the subcommand
   can take the --recursive option.

 * Mishandling of patterns in .gitignore that has trailing SPs quoted
   with backslashes (e.g. ones that end with \ ) have been
   corrected.

 * Recent updates to git repack started to duplicate objects that
   are in packfiles marked with .keep flag into the new packfile by
   mistake.

 * git clone -b brefs/tags/bar would have mistakenly thought we were
   following a single tag, even though it was a name of the branch,
   because it incorrectly used strstr().

 * %G (nothing after G) is an invalid pretty format specifier, but
   the parser did not notice it as garbage.

 * Code to avoid adding the same alternate object store twice was
   subtly broken for a long time, but nobody seems to have noticed.

 * A handful of code paths had to read the commit object more than
   once when showing header fields that are usually not parsed.  The
   internal data structure to keep track of the contents of the commit
   object has been updated to reduce the need for this double-reading,
   and to allow the caller find the length of the object.

 * During git rebase --merge, a conflicted patch could not be
   skipped with --skip if the next one also conflicted.



Changes since v2.0.1 are as follows:

Jeff King (27):
  repack: do not accidentally pack kept objects by default
  repack: respect pack.writebitmaps
  repack: s/write_bitmap/s/ in code
  commit_tree: take a pointer/len pair rather than a const strbuf
  replace dangerous uses of strbuf_attach
  alloc: include any-object allocations in alloc_report
  commit: push commit_index update into alloc_commit_node
  do not create struct commit with xcalloc
  logmsg_reencode: return const buffer
  sequencer: use logmsg_reencode in get_message
  provide a helper to free commit buffer
  provide a helper to set the commit buffer
  provide helpers to access the commit buffer
  use get_cached_commit_buffer where appropriate
  use get_commit_buffer to avoid duplicate code
  convert logmsg_reencode to get_commit_buffer
  use get_commit_buffer everywhere
  commit-slab: provide a static initializer
  commit: convert commit-buffer to a slab
  commit: record buffer length in cache
  reuse cached commit buffer when parsing signatures
  t7510: stop referring to master in later tests
  t7510: test a commit signed by an unknown key
  t7510: check %G* pretty-format output
  pretty: avoid reading past end-of-string with %G
  move %G format test from t7510 to t6006
  t7300: repair filesystem permissions with test_when_finished

Junio C Hamano (4):
  t0008: do not depend on 'echo' handling backslashes specially
  builtin/clone.c: detect a clone starting at a tag correctly
  Start preparing for 2.0.2
  Git 2.0.2

Matthew Chen (1):
  submodule: document sync --recursive

Michael J Gruber (1):
  t7510: use consistent -chains in loop

Pasha Bolokhov (1):
  dir.c:trim_trailing_spaces(): fix for  \  sequence

René Scharfe (2):
  sha1_file: avoid overrunning alternate object base string
  annotate: use argv_array

Ronnie Sahlberg (1):
  enums: remove trailing ',' after last item in enum

brian m. carlson (1):
  rebase--merge: fix --skip with two conflicts in a row

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


Re: [PATCH 2/2] config: use chmod() instead of fchmod()

2014-07-16 Thread Junio C Hamano
Karsten Blees karsten.bl...@gmail.com writes:

 There is no fchmod() on native Windows platforms (MinGW and MSVC), and the
 equivalent Win32 API (SetFileInformationByHandle) requires Windows Vista.

 Use chmod() instead.

 Signed-off-by: Karsten Blees bl...@dcon.de
 ---

I am wondering if it is saner to just revert the fchmod() patch and
replace it with something along the lines of

http://thread.gmane.org/gmane.comp.version-control.git/251682/focus=253219

Having said that, these are the only two callers of fchmod()
currently in our code base, so I'll queue this patch to allow us to
kick the problem-can down the road ;-)

Thanks.

  config.c | 8 
  1 file changed, 4 insertions(+), 4 deletions(-)

 diff --git a/config.c b/config.c
 index ba882a1..9767c4b 100644
 --- a/config.c
 +++ b/config.c
 @@ -1636,8 +1636,8 @@ int git_config_set_multivar_in_file(const char 
 *config_filename,
   MAP_PRIVATE, in_fd, 0);
   close(in_fd);
  
 - if (fchmod(fd, st.st_mode  0)  0) {
 - error(fchmod on %s failed: %s,
 + if (chmod(lock-filename, st.st_mode  0)  0) {
 + error(chmod on %s failed: %s,
   lock-filename, strerror(errno));
   ret = CONFIG_NO_WRITE;
   goto out_free;
 @@ -1815,8 +1815,8 @@ int git_config_rename_section_in_file(const char 
 *config_filename,
  
   fstat(fileno(config_file), st);
  
 - if (fchmod(out_fd, st.st_mode  0)  0) {
 - ret = error(fchmod on %s failed: %s,
 + if (chmod(lock-filename, st.st_mode  0)  0) {
 + ret = error(chmod on %s failed: %s,
   lock-filename, strerror(errno));
   goto out;
   }
 -- 
 2.0.1.779.g26aeac4.dirty

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


Re: [PATCH 00/20] ref transactions part 2

2014-07-16 Thread Junio C Hamano
Ronnie Sahlberg sahlb...@google.com writes:

 On Tue, Jul 15, 2014 at 4:33 PM, Ronnie Sahlberg sahlb...@google.com wrote:
 This is the next 20 patches from my originally big patch series and follow
 the previous 19 patches that is now in juns tree.
 These patches were numbered 20-39 in the original 48-patch series.

 Changes since these patches were in the original series:

 - Addressing concerns from mhagger's review

One patch in the series did not apply cleanly on top of the tip of
the previous series (now queued as rs/ref-transaction-0) and I had
to wiggle it.  Please check the result (queued as three topics, this
one is rs/ref-transaction-1 which is built on the abovementioned
-0, and the remainder from the previous round is rebased on -1
as rs/ref-transaction), all of which are queued on 'jch' (which is
part of 'pu').

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


[PATCH 12/12] refs.c: fix handling of badly named refs

2014-07-16 Thread Ronnie Sahlberg
We currently do not handle badly named refs well :
$ cp .git/refs/heads/master .git/refs/heads/master.@\*@\\.
$ git branch
   fatal: Reference has invalid format: 'refs/heads/master.@*@\.'
$ git branch -D master.@\*@\\.
  error: branch 'master.@*@\.' not found.

But we can not really recover from a badly named ref with less than
manually deleting the .git/refs/heads/refname file.

Change resolve_ref_unsafe to take a flags field instead of a 'reading'
boolean and update all callers that used a non-zero value for reading
to pass the flag RESOLVE_REF_READING instead.
Add another flag RESOLVE_REF_ALLOW_BAD_NAME that will make
resolve_ref_unsafe skip checking the refname for sanity and use this
from branch.c so that we will be able to call resolve_ref_unsafe on such
refs when trying to delete it.
Add checks for refname sanity when updating (not deleting) a ref in
ref_transaction_update and in ref_transaction_create to make the transaction
fail if an attempt is made to create/update a badly named ref.
Since all ref changes will later go through the transaction layer this means
we no longer need to check for and fail for bad refnames in
lock_ref_sha1_basic.

Change lock_ref_sha1_basic to not fail for bad refnames. Just check the
refname, and print an error, and remember that the refname is bad so that
we can skip calling verify_lock().

Allow reading refs with bad names from loose refs and packed refs
but flag them as broken. This means that the refs will at least show up in
git branch even if their name is invalid/broken.

Since we now do the refname checks, when we need to, before the call
to create_ref_entry we can remove the check_name argument to the function.

Signed-off-by: Ronnie Sahlberg sahlb...@google.com
---
 builtin/blame.c |   2 +-
 builtin/branch.c|   6 ++-
 builtin/clone.c |   2 +-
 builtin/fmt-merge-msg.c |   2 +-
 builtin/for-each-ref.c  |   6 ++-
 builtin/log.c   |   3 +-
 builtin/remote.c|   5 +-
 builtin/show-branch.c   |   6 ++-
 bundle.c|   2 +-
 cache.h |  18 ---
 http-backend.c  |   3 +-
 reflog-walk.c   |   3 +-
 refs.c  | 126 ++--
 remote.c|   6 ++-
 sequencer.c |   2 +-
 transport-helper.c  |   2 +-
 transport.c |   5 +-
 17 files changed, 123 insertions(+), 76 deletions(-)

diff --git a/builtin/blame.c b/builtin/blame.c
index 662e3fe..76340e2 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -2278,7 +2278,7 @@ static struct commit *fake_working_tree_commit(struct 
diff_options *opt,
commit-object.type = OBJ_COMMIT;
parent_tail = commit-parents;
 
-   if (!resolve_ref_unsafe(HEAD, head_sha1, 1, NULL))
+   if (!resolve_ref_unsafe(HEAD, head_sha1, RESOLVE_REF_READING, NULL))
die(no such ref: HEAD);
 
parent_tail = append_parent(parent_tail, head_sha1);
diff --git a/builtin/branch.c b/builtin/branch.c
index 652b1d2..5c95656 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -129,7 +129,8 @@ static int branch_merged(int kind, const char *name,
branch-merge[0] 
branch-merge[0]-dst 
(reference_name = reference_name_to_free =
-resolve_refdup(branch-merge[0]-dst, sha1, 1, NULL)) != 
NULL)
+resolve_refdup(branch-merge[0]-dst, sha1,
+   RESOLVE_REF_READING, NULL)) != NULL)
reference_rev = lookup_commit_reference(sha1);
}
if (!reference_rev)
@@ -233,7 +234,8 @@ static int delete_branches(int argc, const char **argv, int 
force, int kinds,
free(name);
 
name = mkpathdup(fmt, bname.buf);
-   target = resolve_ref_unsafe(name, sha1, 0, flags);
+   target = resolve_ref_unsafe(name, sha1,
+   RESOLVE_REF_ALLOW_BAD_NAME, flags);
if (!target ||
(!(flags  REF_ISSYMREF)  is_null_sha1(sha1))) {
error(remote_branch
diff --git a/builtin/clone.c b/builtin/clone.c
index b12989d..f7307e6 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -622,7 +622,7 @@ static int checkout(void)
if (option_no_checkout)
return 0;
 
-   head = resolve_refdup(HEAD, sha1, 1, NULL);
+   head = resolve_refdup(HEAD, sha1, RESOLVE_REF_READING, NULL);
if (!head) {
warning(_(remote HEAD refers to nonexistent ref, 
  unable to checkout.\n));
diff --git a/builtin/fmt-merge-msg.c b/builtin/fmt-merge-msg.c
index 3906eda..d8ab177 100644
--- a/builtin/fmt-merge-msg.c
+++ b/builtin/fmt-merge-msg.c
@@ -602,7 +602,7 @@ int fmt_merge_msg(struct strbuf *in, struct strbuf *out,
 
/* get current branch */
current_branch = current_branch_to_free =
-   

[PATCH 08/12] refs.c: pass a skip list to name_conflict_fn

2014-07-16 Thread Ronnie Sahlberg
Allow passing a list of refs to skip checking to name_conflict_fn.
There are some conditions where we want to allow a temporary conflict and skip
checking those refs. For example if we have a transaction that
1, guarantees that m is a packed refs and there is no loose ref for m
2, the transaction will delete m from the packed ref
3, the transaction will create conflicting m/m

For this case we want to be able to lock and create m/m since we know that the
conflict is only transient. I.e. the conflict will be automatically resolved
by the transaction when it deletes m.

Signed-off-by: Ronnie Sahlberg sahlb...@google.com
---
 refs.c | 41 ++---
 1 file changed, 26 insertions(+), 15 deletions(-)

diff --git a/refs.c b/refs.c
index d3fedbb..a115478 100644
--- a/refs.c
+++ b/refs.c
@@ -801,15 +801,18 @@ static int names_conflict(const char *refname1, const 
char *refname2)
 
 struct name_conflict_cb {
const char *refname;
-   const char *oldrefname;
const char *conflicting_refname;
+   const char **skip;
+   int skipnum;
 };
 
 static int name_conflict_fn(struct ref_entry *entry, void *cb_data)
 {
struct name_conflict_cb *data = (struct name_conflict_cb *)cb_data;
-   if (data-oldrefname  !strcmp(data-oldrefname, entry-name))
-   return 0;
+   int i;
+   for (i = 0; i  data-skipnum; i++)
+   if (!strcmp(entry-name, data-skip[i]))
+   return 0;
if (names_conflict(data-refname, entry-name)) {
data-conflicting_refname = entry-name;
return 1;
@@ -822,15 +825,18 @@ static int name_conflict_fn(struct ref_entry *entry, void 
*cb_data)
  * conflicting with the name of an existing reference in dir.  If
  * oldrefname is non-NULL, ignore potential conflicts with oldrefname
  * (e.g., because oldrefname is scheduled for deletion in the same
- * operation).
+ * operation). skip contains a list of refs we want to skip checking for
+ * conflicts with.
  */
-static int is_refname_available(const char *refname, const char *oldrefname,
-   struct ref_dir *dir)
+static int is_refname_available(const char *refname,
+   struct ref_dir *dir,
+   const char **skip, int skipnum)
 {
struct name_conflict_cb data;
data.refname = refname;
-   data.oldrefname = oldrefname;
data.conflicting_refname = NULL;
+   data.skip = skip;
+   data.skipnum = skipnum;
 
sort_ref_dir(dir);
if (do_for_each_entry_in_dir(dir, 0, name_conflict_fn, data)) {
@@ -2077,7 +2083,8 @@ int dwim_log(const char *str, int len, unsigned char 
*sha1, char **log)
 /* This function should make sure errno is meaningful on error */
 static struct ref_lock *lock_ref_sha1_basic(const char *refname,
const unsigned char *old_sha1,
-   int flags, int *type_p)
+   int flags, int *type_p,
+   const char **skip, int skipnum)
 {
char *ref_file;
const char *orig_refname = refname;
@@ -2126,7 +2133,8 @@ static struct ref_lock *lock_ref_sha1_basic(const char 
*refname,
 * name is a proper prefix of our refname.
 */
if (missing 
-!is_refname_available(refname, NULL, get_packed_refs(ref_cache))) 
{
+!is_refname_available(refname, get_packed_refs(ref_cache),
+  skip, skipnum)) {
last_errno = ENOTDIR;
goto error_return;
}
@@ -2184,7 +2192,7 @@ struct ref_lock *lock_any_ref_for_update(const char 
*refname,
 const unsigned char *old_sha1,
 int flags, int *type_p)
 {
-   return lock_ref_sha1_basic(refname, old_sha1, flags, type_p);
+   return lock_ref_sha1_basic(refname, old_sha1, flags, type_p, NULL, 0);
 }
 
 /*
@@ -2654,10 +2662,12 @@ int rename_ref(const char *oldrefname, const char 
*newrefname, const char *logms
if (!symref)
return error(refname %s not found, oldrefname);
 
-   if (!is_refname_available(newrefname, oldrefname, 
get_packed_refs(ref_cache)))
+   if (!is_refname_available(newrefname, get_packed_refs(ref_cache),
+ oldrefname, 1))
return 1;
 
-   if (!is_refname_available(newrefname, oldrefname, 
get_loose_refs(ref_cache)))
+   if (!is_refname_available(newrefname, get_loose_refs(ref_cache),
+ oldrefname, 1))
return 1;
 
if (log  rename(git_path(logs/%s, oldrefname), 
git_path(TMP_RENAMED_LOG)))
@@ -2687,7 +2697,7 @@ int rename_ref(const char *oldrefname, const char 
*newrefname, const char *logms
 
logmoved = log;
 
-   lock = 

[PATCH 01/12] wrapper.c: simplify warn_if_unremovable

2014-07-16 Thread Ronnie Sahlberg
Signed-off-by: Ronnie Sahlberg sahlb...@google.com
---
 wrapper.c | 14 ++
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/wrapper.c b/wrapper.c
index bc1bfb8..740e193 100644
--- a/wrapper.c
+++ b/wrapper.c
@@ -429,14 +429,12 @@ int xmkstemp_mode(char *template, int mode)
 
 static int warn_if_unremovable(const char *op, const char *file, int rc)
 {
-   if (rc  0) {
-   int err = errno;
-   if (ENOENT != err) {
-   warning(unable to %s %s: %s,
-   op, file, strerror(errno));
-   errno = err;
-   }
-   }
+   int err;
+   if (rc = 0 || errno == ENOENT)
+   return rc;
+   err = errno;
+   warning(unable to %s %s: %s, op, file, strerror(errno));
+   errno = err;
return rc;
 }
 
-- 
2.0.1.527.gc6b782e

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


[PATCH 03/12] refs.c: add an err argument to delete_ref_loose

2014-07-16 Thread Ronnie Sahlberg
Add an err argument to delete_loose_ref so that we can pass a descriptive
error string back to the caller. Pass the err argument from transaction
commit to this function so that transaction users will have a nice error
string if the transaction failed due to delete_loose_ref.

Signed-off-by: Ronnie Sahlberg sahlb...@google.com
---
 refs.c | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/refs.c b/refs.c
index 0017d9c..24f9546 100644
--- a/refs.c
+++ b/refs.c
@@ -2544,16 +2544,16 @@ int repack_without_refs(const char **refnames, int n, 
struct strbuf *err)
return ret;
 }
 
-static int delete_ref_loose(struct ref_lock *lock, int flag)
+static int delete_ref_loose(struct ref_lock *lock, int flag, struct strbuf 
*err)
 {
if (!(flag  REF_ISPACKED) || flag  REF_ISSYMREF) {
/* loose */
-   int err, i = strlen(lock-lk-filename) - 5; /* .lock */
+   int res, i = strlen(lock-lk-filename) - 5; /* .lock */
 
lock-lk-filename[i] = 0;
-   err = unlink_or_warn(lock-lk-filename);
+   res = unlink_or_msg(lock-lk-filename, err);
lock-lk-filename[i] = '.';
-   if (err  errno != ENOENT)
+   if (res)
return 1;
}
return 0;
@@ -3602,7 +3602,8 @@ int ref_transaction_commit(struct ref_transaction 
*transaction,
struct ref_update *update = updates[i];
 
if (update-lock) {
-   ret |= delete_ref_loose(update-lock, update-type);
+   ret |= delete_ref_loose(update-lock, update-type,
+   err);
if (!(update-flags  REF_ISPRUNING))
delnames[delnum++] = update-lock-ref_name;
}
-- 
2.0.1.527.gc6b782e

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


[PATCH 04/12] refs.c: pass the ref log message to _create/delete/update instead of _commit

2014-07-16 Thread Ronnie Sahlberg
Change the reference transactions so that we pass the reflog message
through to the create/delete/update function instead of the commit message.
This allows for individual messages for each change in a multi ref
transaction.

Reviewed-by: Jonathan Nieder jrnie...@gmail.com
Signed-off-by: Ronnie Sahlberg sahlb...@google.com
---
 branch.c   |  4 ++--
 builtin/commit.c   |  4 ++--
 builtin/fetch.c|  3 +--
 builtin/receive-pack.c |  5 +++--
 builtin/replace.c  |  4 ++--
 builtin/tag.c  |  4 ++--
 builtin/update-ref.c   | 13 +++--
 fast-import.c  |  8 
 refs.c | 34 +-
 refs.h |  8 
 sequencer.c|  4 ++--
 walker.c   |  5 ++---
 12 files changed, 52 insertions(+), 44 deletions(-)

diff --git a/branch.c b/branch.c
index c1eae00..e0439af 100644
--- a/branch.c
+++ b/branch.c
@@ -301,8 +301,8 @@ void create_branch(const char *head,
transaction = ref_transaction_begin(err);
if (!transaction ||
ref_transaction_update(transaction, ref.buf, sha1,
-  null_sha1, 0, !forcing, err) ||
-   ref_transaction_commit(transaction, msg, err))
+  null_sha1, 0, !forcing, msg, err) ||
+   ref_transaction_commit(transaction, err))
die(%s, err.buf);
ref_transaction_free(transaction);
}
diff --git a/builtin/commit.c b/builtin/commit.c
index 668fa6a..c499826 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -1767,8 +1767,8 @@ int cmd_commit(int argc, const char **argv, const char 
*prefix)
ref_transaction_update(transaction, HEAD, sha1,
   current_head ?
   current_head-object.sha1 : NULL,
-  0, !!current_head, err) ||
-   ref_transaction_commit(transaction, sb.buf, err)) {
+  0, !!current_head, sb.buf, err) ||
+   ref_transaction_commit(transaction, err)) {
rollback_index_files();
die(%s, err.buf);
}
diff --git a/builtin/fetch.c b/builtin/fetch.c
index dd46b61..92fad2d 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -702,10 +702,9 @@ static int store_updated_refs(const char *raw_url, const 
char *remote_name,
}
}
}
-
if (rc  STORE_REF_ERROR_DF_CONFLICT)
error(_(some local refs could not be updated; try running\n
-  'git remote prune %s' to remove any old, conflicting 
+ 'git remote prune %s' to remove any old, conflicting 
  branches), remote_name);
 
  abort:
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 91099ad..4752225 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -585,8 +585,9 @@ static char *update(struct command *cmd, struct 
shallow_info *si)
transaction = ref_transaction_begin(err);
if (!transaction ||
ref_transaction_update(transaction, namespaced_name,
-  new_sha1, old_sha1, 0, 1, err) ||
-   ref_transaction_commit(transaction, push, err)) {
+  new_sha1, old_sha1, 0, 1, push,
+  err) ||
+   ref_transaction_commit(transaction, err)) {
char *str = strbuf_detach(err, NULL);
ref_transaction_free(transaction);
 
diff --git a/builtin/replace.c b/builtin/replace.c
index 7528f3d..df060f8 100644
--- a/builtin/replace.c
+++ b/builtin/replace.c
@@ -170,8 +170,8 @@ static int replace_object_sha1(const char *object_ref,
transaction = ref_transaction_begin(err);
if (!transaction ||
ref_transaction_update(transaction, ref, repl, prev,
-  0, !is_null_sha1(prev), err) ||
-   ref_transaction_commit(transaction, NULL, err))
+  0, !is_null_sha1(prev), NULL, err) ||
+   ref_transaction_commit(transaction, err))
die(%s, err.buf);
 
ref_transaction_free(transaction);
diff --git a/builtin/tag.c b/builtin/tag.c
index 1aa88a2..3834b06 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -705,8 +705,8 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
transaction = ref_transaction_begin(err);
if (!transaction ||
ref_transaction_update(transaction, ref.buf, object, prev,
-  0, 1, err) ||
-   ref_transaction_commit(transaction, NULL, err))
+  0, 1, NULL, err) ||
+   ref_transaction_commit(transaction, err))

[PATCH 05/12] refs.c: pass NULL as *flags to read_ref_full

2014-07-16 Thread Ronnie Sahlberg
We call read_ref_full with a pointer to flags from rename_ref but since
we never actually use the returned flags we can just pass NULL here instead.

Reviewed-by: Jonathan Nieder jrnie...@gmail.com
Signed-off-by: Ronnie Sahlberg sahlb...@google.com
---
 refs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/refs.c b/refs.c
index 7d65253..0df6894 100644
--- a/refs.c
+++ b/refs.c
@@ -2666,7 +2666,7 @@ int rename_ref(const char *oldrefname, const char 
*newrefname, const char *logms
goto rollback;
}
 
-   if (!read_ref_full(newrefname, sha1, 1, flag) 
+   if (!read_ref_full(newrefname, sha1, 1, NULL) 
delete_ref(newrefname, sha1, REF_NODEREF)) {
if (errno==EISDIR) {
if (remove_empty_directories(git_path(%s, 
newrefname))) {
-- 
2.0.1.527.gc6b782e

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


[PATCH 00/12] Use ref transactions part 3

2014-07-16 Thread Ronnie Sahlberg
This is the third and final part of the original 48 patch series for
basic transaction support.

It is used ontop of the previous two series :
* rs/ref-transaction-0 (2014-07-14) 19 commits
* rs/ref-transaction-1 (2014-07-16) 20 commits

This version implements some changes suggested by mhagger for the
warn_if_removable changes.
It also adds a new patch fix handling of badly named refs that repairs
the handling of badly named refs.


Ronnie Sahlberg (12):
  wrapper.c: simplify warn_if_unremovable
  wrapper.c: add a new function unlink_or_msg
  refs.c: add an err argument to delete_ref_loose
  refs.c: pass the ref log message to _create/delete/update instead of
_commit
  refs.c: pass NULL as *flags to read_ref_full
  refs.c: move the check for valid refname to lock_ref_sha1_basic
  refs.c: call lock_ref_sha1_basic directly from commit
  refs.c: pass a skip list to name_conflict_fn
  refs.c: propagate any errno==ENOTDIR from _commit back to the callers
  fetch.c: change s_update_ref to use a ref transaction
  refs.c: make write_ref_sha1 static
  refs.c: fix handling of badly named refs

 branch.c|   4 +-
 builtin/blame.c |   2 +-
 builtin/branch.c|   6 +-
 builtin/clone.c |   2 +-
 builtin/commit.c|   4 +-
 builtin/fetch.c |  36 ---
 builtin/fmt-merge-msg.c |   2 +-
 builtin/for-each-ref.c  |   6 +-
 builtin/log.c   |   3 +-
 builtin/receive-pack.c  |   5 +-
 builtin/remote.c|   5 +-
 builtin/replace.c   |   4 +-
 builtin/show-branch.c   |   6 +-
 builtin/tag.c   |   4 +-
 builtin/update-ref.c|  13 +--
 bundle.c|   2 +-
 cache.h |  18 ++--
 fast-import.c   |   8 +-
 git-compat-util.h   |   6 ++
 http-backend.c  |   3 +-
 reflog-walk.c   |   3 +-
 refs.c  | 247 +++-
 refs.h  |  17 ++--
 remote.c|   6 +-
 sequencer.c |   6 +-
 transport-helper.c  |   2 +-
 transport.c |   5 +-
 walker.c|   5 +-
 wrapper.c   |  30 --
 29 files changed, 291 insertions(+), 169 deletions(-)

-- 
2.0.1.527.gc6b782e

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


[PATCH 07/12] refs.c: call lock_ref_sha1_basic directly from commit

2014-07-16 Thread Ronnie Sahlberg
Skip using the lock_any_ref_for_update wrapper and call lock_ref_sha1_basic
directly from the commit function.

Reviewed-by: Jonathan Nieder jrnie...@gmail.com
Signed-off-by: Ronnie Sahlberg sahlb...@google.com
---
 refs.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/refs.c b/refs.c
index f29f18a..d3fedbb 100644
--- a/refs.c
+++ b/refs.c
@@ -3575,12 +3575,12 @@ int ref_transaction_commit(struct ref_transaction 
*transaction,
for (i = 0; i  n; i++) {
struct ref_update *update = updates[i];
 
-   update-lock = lock_any_ref_for_update(update-refname,
-  (update-have_old ?
-   update-old_sha1 :
-   NULL),
-  update-flags,
-  update-type);
+   update-lock = lock_ref_sha1_basic(update-refname,
+  (update-have_old ?
+   update-old_sha1 :
+   NULL),
+  update-flags,
+  update-type);
if (!update-lock) {
if (err)
strbuf_addf(err, Cannot lock the ref '%s'.,
-- 
2.0.1.527.gc6b782e

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


[PATCH 10/12] fetch.c: change s_update_ref to use a ref transaction

2014-07-16 Thread Ronnie Sahlberg
Change s_update_ref to use a ref transaction for the ref update.

Signed-off-by: Ronnie Sahlberg sahlb...@google.com
---
 builtin/fetch.c | 33 +++--
 1 file changed, 23 insertions(+), 10 deletions(-)

diff --git a/builtin/fetch.c b/builtin/fetch.c
index 92fad2d..383c385 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -404,23 +404,36 @@ static int s_update_ref(const char *action,
 {
char msg[1024];
char *rla = getenv(GIT_REFLOG_ACTION);
-   static struct ref_lock *lock;
+   struct ref_transaction *transaction;
+   struct strbuf err = STRBUF_INIT;
+   int ret, df_conflict = 0;
 
if (dry_run)
return 0;
if (!rla)
rla = default_rla.buf;
snprintf(msg, sizeof(msg), %s: %s, rla, action);
-   lock = lock_any_ref_for_update(ref-name,
-  check_old ? ref-old_sha1 : NULL,
-  0, NULL);
-   if (!lock)
-   return errno == ENOTDIR ? STORE_REF_ERROR_DF_CONFLICT :
- STORE_REF_ERROR_OTHER;
-   if (write_ref_sha1(lock, ref-new_sha1, msg)  0)
-   return errno == ENOTDIR ? STORE_REF_ERROR_DF_CONFLICT :
- STORE_REF_ERROR_OTHER;
+
+   transaction = ref_transaction_begin(err);
+   if (!transaction ||
+   ref_transaction_update(transaction, ref-name, ref-new_sha1,
+  ref-old_sha1, 0, check_old, msg, err))
+   goto fail;
+
+   ret = ref_transaction_commit(transaction, err);
+   if (ret == UPDATE_REFS_NAME_CONFLICT)
+   df_conflict = 1;
+   if (ret)
+   goto fail;
+
+   ref_transaction_free(transaction);
return 0;
+fail:
+   ref_transaction_free(transaction);
+   error(%s, err.buf);
+   strbuf_release(err);
+   return df_conflict ? STORE_REF_ERROR_DF_CONFLICT
+  : STORE_REF_ERROR_OTHER;
 }
 
 #define REFCOL_WIDTH  10
-- 
2.0.1.527.gc6b782e

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


[PATCH 02/12] wrapper.c: add a new function unlink_or_msg

2014-07-16 Thread Ronnie Sahlberg
Signed-off-by: Ronnie Sahlberg sahlb...@google.com
---
 git-compat-util.h |  6 ++
 wrapper.c | 18 ++
 2 files changed, 24 insertions(+)

diff --git a/git-compat-util.h b/git-compat-util.h
index b6f03b3..426bc98 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -704,12 +704,18 @@ void git_qsort(void *base, size_t nmemb, size_t size,
 #endif
 #endif
 
+#include strbuf.h
+
 /*
  * Preserves errno, prints a message, but gives no warning for ENOENT.
  * Always returns the return value of unlink(2).
  */
 int unlink_or_warn(const char *path);
 /*
+ * Like unlink_or_warn but populates a strbuf
+ */
+int unlink_or_msg(const char *file, struct strbuf *err);
+/*
  * Likewise for rmdir(2).
  */
 int rmdir_or_warn(const char *path);
diff --git a/wrapper.c b/wrapper.c
index 740e193..74a0cc0 100644
--- a/wrapper.c
+++ b/wrapper.c
@@ -438,6 +438,24 @@ static int warn_if_unremovable(const char *op, const char 
*file, int rc)
return rc;
 }
 
+int unlink_or_msg(const char *file, struct strbuf *err)
+{
+   if (err) {
+   int rc = unlink(file);
+   int save_errno = errno;
+
+   if (rc  0  errno != ENOENT) {
+   strbuf_addf(err, unable to unlink %s: %s,
+   file, strerror(errno));
+   errno = save_errno;
+   return -1;
+   }
+   return 0;
+   }
+
+   return unlink_or_warn(file);
+}
+
 int unlink_or_warn(const char *file)
 {
return warn_if_unremovable(unlink, file, unlink(file));
-- 
2.0.1.527.gc6b782e

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


[PATCH 06/12] refs.c: move the check for valid refname to lock_ref_sha1_basic

2014-07-16 Thread Ronnie Sahlberg
Move the check for check_refname_format from lock_any_ref_for_update
to lock_ref_sha1_basic. At some later stage we will get rid of
lock_any_ref_for_update completely.

If lock_ref_sha1_basic fails the check_refname_format test, set errno to
EINVAL before returning NULL. This to guarantee that we will not return an
error without updating errno.

This leaves lock_any_ref_for_updates as a no-op wrapper which could be removed.
But this wrapper is also called from an external caller and we will soon
make changes to the signature to lock_ref_sha1_basic that we do not want to
expose to that caller.

This changes semantics for lock_ref_sha1_basic slightly. With this change
it is no longer possible to open a ref that has a badly name which breaks
any codepaths that tries to open and repair badly named refs. The normal refs
API should not allow neither creating nor accessing refs with invalid names.
If we need such recovery code we could add it as an option to git fsck and have
git fsck be the only sanctioned way of bypassing the normal API and checks.

Signed-off-by: Ronnie Sahlberg sahlb...@google.com
---
 refs.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/refs.c b/refs.c
index 0df6894..f29f18a 100644
--- a/refs.c
+++ b/refs.c
@@ -2088,6 +2088,11 @@ static struct ref_lock *lock_ref_sha1_basic(const char 
*refname,
int missing = 0;
int attempts_remaining = 3;
 
+   if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {
+   errno = EINVAL;
+   return NULL;
+   }
+
lock = xcalloc(1, sizeof(struct ref_lock));
lock-lock_fd = -1;
 
@@ -2179,8 +2184,6 @@ struct ref_lock *lock_any_ref_for_update(const char 
*refname,
 const unsigned char *old_sha1,
 int flags, int *type_p)
 {
-   if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL))
-   return NULL;
return lock_ref_sha1_basic(refname, old_sha1, flags, type_p);
 }
 
-- 
2.0.1.527.gc6b782e

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


[PATCH 09/12] refs.c: propagate any errno==ENOTDIR from _commit back to the callers

2014-07-16 Thread Ronnie Sahlberg
In _commit, ENOTDIR can happen in the call to lock_ref_sha1_basic, either when
we lstat the new refname and it returns ENOTDIR or if the name checking
function reports that the same type of conflict happened. In both cases it
means that we can not create the new ref due to a name conflict.

For these cases, save the errno value and abort and make sure that the caller
can see errno==ENOTDIR.

Also start defining specific return codes for _commit, assign -1 as a generic
error and -2 as the error that refers to a name conflict. Callers can (and
should) use that return value inspecting errno directly.

Signed-off-by: Ronnie Sahlberg sahlb...@google.com
---
 refs.c | 22 +++---
 refs.h |  6 ++
 2 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/refs.c b/refs.c
index a115478..69cbca5 100644
--- a/refs.c
+++ b/refs.c
@@ -3559,7 +3559,7 @@ static int ref_update_reject_duplicates(struct ref_update 
**updates, int n,
 int ref_transaction_commit(struct ref_transaction *transaction,
   struct strbuf *err)
 {
-   int ret = 0, delnum = 0, i;
+   int ret = 0, delnum = 0, i, df_conflict = 0;
const char **delnames;
int n = transaction-nr;
struct ref_update **updates = transaction-updates;
@@ -3577,9 +3577,10 @@ int ref_transaction_commit(struct ref_transaction 
*transaction,
 
/* Copy, sort, and reject duplicate refs */
qsort(updates, n, sizeof(*updates), ref_update_compare);
-   ret = ref_update_reject_duplicates(updates, n, err);
-   if (ret)
+   if (ref_update_reject_duplicates(updates, n, err)) {
+   ret = -1;
goto cleanup;
+   }
 
/* Acquire all locks while verifying old values */
for (i = 0; i  n; i++) {
@@ -3593,10 +3594,12 @@ int ref_transaction_commit(struct ref_transaction 
*transaction,
   update-type,
   delnames, delnum);
if (!update-lock) {
+   if (errno == ENOTDIR)
+   df_conflict = 1;
if (err)
strbuf_addf(err, Cannot lock the ref '%s'.,
update-refname);
-   ret = 1;
+   ret = -1;
goto cleanup;
}
}
@@ -3614,6 +3617,7 @@ int ref_transaction_commit(struct ref_transaction 
*transaction,
 
if (err)
strbuf_addf(err, str, update-refname);
+   ret = -1;
goto cleanup;
}
}
@@ -3624,14 +3628,16 @@ int ref_transaction_commit(struct ref_transaction 
*transaction,
struct ref_update *update = updates[i];
 
if (update-lock) {
-   ret |= delete_ref_loose(update-lock, update-type,
-   err);
+   if (delete_ref_loose(update-lock, update-type, err))
+   ret = -1;
+
if (!(update-flags  REF_ISPRUNING))
delnames[delnum++] = update-lock-ref_name;
}
}
 
-   ret |= repack_without_refs(delnames, delnum, err);
+   if (repack_without_refs(delnames, delnum, err))
+   ret = -1;
for (i = 0; i  delnum; i++)
unlink_or_warn(git_path(logs/%s, delnames[i]));
clear_loose_ref_cache(ref_cache);
@@ -3644,6 +3650,8 @@ cleanup:
if (updates[i]-lock)
unlock_ref(updates[i]-lock);
free(delnames);
+   if (df_conflict)
+   ret = -2;
return ret;
 }
 
diff --git a/refs.h b/refs.h
index 6a4d1a7..fc7942c 100644
--- a/refs.h
+++ b/refs.h
@@ -326,7 +326,13 @@ int ref_transaction_delete(struct ref_transaction 
*transaction,
  * Commit all of the changes that have been queued in transaction, as
  * atomically as possible.  Return a nonzero value if there is a
  * problem.
+ * If the transaction is already in failed state this function will return
+ * an error.
+ * Function returns 0 on success, -1 for generic failures and
+ * UPDATE_REFS_NAME_CONFLICT (-2) if the failure was due to a name
+ * collision (ENOTDIR).
  */
+#define UPDATE_REFS_NAME_CONFLICT -2
 int ref_transaction_commit(struct ref_transaction *transaction,
   struct strbuf *err);
 
-- 
2.0.1.527.gc6b782e

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


[PATCH 11/12] refs.c: make write_ref_sha1 static

2014-07-16 Thread Ronnie Sahlberg
No external users call write_ref_sha1 any more so lets declare it static.

Signed-off-by: Ronnie Sahlberg sahlb...@google.com
---
 refs.c | 10 --
 refs.h |  3 ---
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/refs.c b/refs.c
index 69cbca5..6c7a9d2 100644
--- a/refs.c
+++ b/refs.c
@@ -2643,6 +2643,9 @@ static int rename_tmp_log(const char *newrefname)
return 0;
 }
 
+static int write_ref_sha1(struct ref_lock *lock, const unsigned char *sha1,
+ const char *logmsg);
+
 int rename_ref(const char *oldrefname, const char *newrefname, const char 
*logmsg)
 {
unsigned char sha1[20], orig_sha1[20];
@@ -2892,8 +2895,11 @@ static int is_branch(const char *refname)
return !strcmp(refname, HEAD) || starts_with(refname, refs/heads/);
 }
 
-/* This function must return a meaningful errno */
-int write_ref_sha1(struct ref_lock *lock,
+/*
+ * Writes sha1 into the ref specified by the lock. Makes sure that errno
+ * is sane on error.
+ */
+static int write_ref_sha1(struct ref_lock *lock,
const unsigned char *sha1, const char *logmsg)
 {
static char term = '\n';
diff --git a/refs.h b/refs.h
index fc7942c..b0476c1 100644
--- a/refs.h
+++ b/refs.h
@@ -196,9 +196,6 @@ extern int commit_ref(struct ref_lock *lock);
 /** Release any lock taken but not written. **/
 extern void unlock_ref(struct ref_lock *lock);
 
-/** Writes sha1 into the ref specified by the lock. **/
-extern int write_ref_sha1(struct ref_lock *lock, const unsigned char *sha1, 
const char *msg);
-
 /*
  * Setup reflog before using. Set errno to something meaningful on failure.
  */
-- 
2.0.1.527.gc6b782e

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


Re: What's cooking in git.git (Jul 2014, #03; Wed, 16)

2014-07-16 Thread Junio C Hamano
On Wed, Jul 16, 2014 at 3:01 PM, Junio C Hamano gits...@pobox.com wrote:
 Here are the topics that have been cooking.  Commits prefixed with
 '-' are only in 'pu' (proposed updates) while commits prefixed with
 '+' are in 'next'.

 We would need to start slowing down to prepare for -rc0 preview at
 the end of this week and then feature freeze.  Some topics that
 joined 'next' late may want to stay there for the remainder of this
 cycle.  Many of the accumulated fixes have been flushed to 'maint'
 and Git 2.0.2 has been tagged.

Oops; I've been hoping that we will have -rc0 at the end of next week,
not this week.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 00/20] ref transactions part 2

2014-07-16 Thread Ronnie Sahlberg
I had a look at the changes in origin/pu and they look sane to me.

make test   passes all tests too.


regards
ronnie sahlberg


On Wed, Jul 16, 2014 at 3:16 PM, Junio C Hamano gits...@pobox.com wrote:
 Ronnie Sahlberg sahlb...@google.com writes:

 On Tue, Jul 15, 2014 at 4:33 PM, Ronnie Sahlberg sahlb...@google.com wrote:
 This is the next 20 patches from my originally big patch series and follow
 the previous 19 patches that is now in juns tree.
 These patches were numbered 20-39 in the original 48-patch series.

 Changes since these patches were in the original series:

 - Addressing concerns from mhagger's review

 One patch in the series did not apply cleanly on top of the tip of
 the previous series (now queued as rs/ref-transaction-0) and I had
 to wiggle it.  Please check the result (queued as three topics, this
 one is rs/ref-transaction-1 which is built on the abovementioned
 -0, and the remainder from the previous round is rebased on -1
 as rs/ref-transaction), all of which are queued on 'jch' (which is
 part of 'pu').

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


[PATCH] strbuf: use strbuf_addstr() for adding C strings

2014-07-16 Thread René Scharfe
Avoid code duplication and let strbuf_addstr() call strlen() for us.

Signed-off-by: Rene Scharfe l@web.de
---
 builtin/commit.c |  2 +-
 diff.c   | 12 ++--
 path.c   |  6 +++---
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/builtin/commit.c b/builtin/commit.c
index 72eb3be..f2d7979 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -702,7 +702,7 @@ static int prepare_to_commit(const char *index_file, const 
char *prefix,
char *buffer;
buffer = strstr(use_message_buffer, \n\n);
if (buffer)
-   strbuf_add(sb, buffer + 2, strlen(buffer + 2));
+   strbuf_addstr(sb, buffer + 2);
hook_arg1 = commit;
hook_arg2 = use_message;
} else if (fixup_message) {
diff --git a/diff.c b/diff.c
index 06bdfb8..867f034 100644
--- a/diff.c
+++ b/diff.c
@@ -525,9 +525,9 @@ static void emit_hunk_header(struct emit_callback *ecbdata,
ep += 2; /* skip over @@ */
 
/* The hunk header in fraginfo color */
-   strbuf_add(msgbuf, frag, strlen(frag));
+   strbuf_addstr(msgbuf, frag);
strbuf_add(msgbuf, line, ep - line);
-   strbuf_add(msgbuf, reset, strlen(reset));
+   strbuf_addstr(msgbuf, reset);
 
/*
 * trailing \r\n
@@ -541,15 +541,15 @@ static void emit_hunk_header(struct emit_callback 
*ecbdata,
if (*ep != ' '  *ep != '\t')
break;
if (ep != cp) {
-   strbuf_add(msgbuf, plain, strlen(plain));
+   strbuf_addstr(msgbuf, plain);
strbuf_add(msgbuf, cp, ep - cp);
-   strbuf_add(msgbuf, reset, strlen(reset));
+   strbuf_addstr(msgbuf, reset);
}
 
if (ep  line + len) {
-   strbuf_add(msgbuf, func, strlen(func));
+   strbuf_addstr(msgbuf, func);
strbuf_add(msgbuf, ep, line + len - ep);
-   strbuf_add(msgbuf, reset, strlen(reset));
+   strbuf_addstr(msgbuf, reset);
}
 
strbuf_add(msgbuf, line + len, org_len - len);
diff --git a/path.c b/path.c
index bc804a3..c3883d4 100644
--- a/path.c
+++ b/path.c
@@ -277,16 +277,16 @@ char *expand_user_path(const char *path)
const char *home = getenv(HOME);
if (!home)
goto return_null;
-   strbuf_add(user_path, home, strlen(home));
+   strbuf_addstr(user_path, home);
} else {
struct passwd *pw = getpw_str(username, username_len);
if (!pw)
goto return_null;
-   strbuf_add(user_path, pw-pw_dir, strlen(pw-pw_dir));
+   strbuf_addstr(user_path, pw-pw_dir);
}
to_copy = first_slash;
}
-   strbuf_add(user_path, to_copy, strlen(to_copy));
+   strbuf_addstr(user_path, to_copy);
return strbuf_detach(user_path, NULL);
 return_null:
strbuf_release(user_path);
-- 
2.0.2

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


Re: [PATCH] strbuf: use strbuf_addstr() for adding C strings

2014-07-16 Thread Jonathan Nieder
René Scharfe wrote:

 Avoid code duplication and let strbuf_addstr() call strlen() for us.

Nice.

 Signed-off-by: Rene Scharfe l@web.de
 ---
  builtin/commit.c |  2 +-
  diff.c   | 12 ++--
  path.c   |  6 +++---
  3 files changed, 10 insertions(+), 10 deletions(-)

Reviewed-by: Jonathan Nieder jrnie...@gmail.com
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] use commit_list_count() to count the members of commit_lists

2014-07-16 Thread René Scharfe
Call commit_list_count() instead of open-coding it repeatedly.

Signed-off-by: Rene Scharfe l@web.de

---
 builtin/blame.c|  5 +
 builtin/for-each-ref.c | 16 ++--
 commit.c   |  7 +--
 line-log.c | 13 +
 pretty.c   |  7 +--
 5 files changed, 6 insertions(+), 42 deletions(-)

diff --git a/builtin/blame.c b/builtin/blame.c
index c59e702..339a8d0 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -1371,11 +1371,8 @@ static struct commit_list *first_scapegoat(struct 
rev_info *revs, struct commit
 
 static int num_scapegoats(struct rev_info *revs, struct commit *commit)
 {
-   int cnt;
struct commit_list *l = first_scapegoat(revs, commit);
-   for (cnt = 0; l; l = l-next)
-   cnt++;
-   return cnt;
+   return commit_list_count(l);
 }
 
 /* Distribute collected unsorted blames to the respected sorted lists
diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c
index 4135980..47bd624 100644
--- a/builtin/for-each-ref.c
+++ b/builtin/for-each-ref.c
@@ -283,18 +283,6 @@ static void grab_tag_values(struct atom_value *val, int 
deref, struct object *ob
}
 }
 
-static int num_parents(struct commit *commit)
-{
-   struct commit_list *parents;
-   int i;
-
-   for (i = 0, parents = commit-parents;
-parents;
-parents = parents-next)
-   i++;
-   return i;
-}
-
 /* See grab_values */
 static void grab_commit_values(struct atom_value *val, int deref, struct 
object *obj, void *buf, unsigned long sz)
 {
@@ -315,12 +303,12 @@ static void grab_commit_values(struct atom_value *val, 
int deref, struct object
}
if (!strcmp(name, numparent)) {
char *s = xmalloc(40);
-   v-ul = num_parents(commit);
+   v-ul = commit_list_count(commit-parents);
sprintf(s, %lu, v-ul);
v-s = s;
}
else if (!strcmp(name, parent)) {
-   int num = num_parents(commit);
+   int num = commit_list_count(commit-parents);
int i;
struct commit_list *parents;
char *s = xmalloc(41 * num + 1);
diff --git a/commit.c b/commit.c
index f43970d..e9c40f7 100644
--- a/commit.c
+++ b/commit.c
@@ -987,12 +987,7 @@ struct commit_list *get_merge_bases_many(struct commit 
*one,
}
 
/* There are more than one */
-   cnt = 0;
-   list = result;
-   while (list) {
-   list = list-next;
-   cnt++;
-   }
+   cnt = commit_list_count(result);
rslt = xcalloc(cnt, sizeof(*rslt));
for (list = result, i = 0; list; list = list-next)
rslt[i++] = list-item;
diff --git a/line-log.c b/line-log.c
index afcc98d..1008e72 100644
--- a/line-log.c
+++ b/line-log.c
@@ -766,17 +766,6 @@ void line_log_init(struct rev_info *rev, const char 
*prefix, struct string_list
}
 }
 
-static int count_parents(struct commit *commit)
-{
-   struct commit_list *parents = commit-parents;
-   int count = 0;
-   while (parents) {
-   count++;
-   parents = parents-next;
-   }
-   return count;
-}
-
 static void move_diff_queue(struct diff_queue_struct *dst,
struct diff_queue_struct *src)
 {
@@ -1150,7 +1139,7 @@ static int process_ranges_merge_commit(struct rev_info 
*rev, struct commit *comm
struct commit **parents;
struct commit_list *p;
int i;
-   int nparents = count_parents(commit);
+   int nparents = commit_list_count(commit-parents);
 
diffqueues = xmalloc(nparents * sizeof(*diffqueues));
cand = xmalloc(nparents * sizeof(*cand));
diff --git a/pretty.c b/pretty.c
index eb676d6..3a1da6f 100644
--- a/pretty.c
+++ b/pretty.c
@@ -1554,12 +1554,7 @@ static void pp_header(struct pretty_print_context *pp,
}
 
if (!parents_shown) {
-   struct commit_list *parent;
-   int num;
-   for (parent = commit-parents, num = 0;
-parent;
-parent = parent-next, num++)
-   ;
+   unsigned num = commit_list_count(commit-parents);
/* with enough slop */
strbuf_grow(sb, num * 50 + 20);
add_merge_info(pp, sb, commit);
-- 
2.0.2

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


git update-index not delete lock file when using different worktree

2014-07-16 Thread Yue Lin Ho
This is a [issue from
TortoiseGit](https://code.google.com/p/tortoisegit/issues/detail?id=2233).
After doing some test, I report it here.
The following is the testing information I have tested.

### Folder Structure
```
Test
  |-- myrepo
  | |-- bar.txt
  | |-- foo.txt
  |
  |-- myrepo.git
|-- .git
```
Testing repository is
[here](https://code.google.com/p/tortoisegit/issues/detail?id=2233#c2).

### Using different worktree
Set the config file (in the .git folder)
```
[core]
worktree = ../../myrepo
```

### Test 1 - Git Bash
```
User@PC /d/Repo/myrepo.git (master)
$ git --version
git version 1.9.4.msysgit.0

User@PC /d/Repo/myrepo.git (master)
$ git update-index --refresh
fatal: Unable to write new index file
```
D:\Repo\myrepo.git\\**index.lock** is not deleted.

### Test 2 - Git 2.0.0
Copy testing repository into ```C:\msysgit\MyTest```

Execute```msys.bat```
```$ vagrant up```
```$ vagrant ssh```
```vagrant@precise64:/vagrant/git$ cd /vagrant```
```vagrant@precise64:/vagrant$ cd mytest/myrepo.git```
```
vagrant@precise64:/vagrant/mytest/myrepo.git$ git --version
git version 2.0.0
```
```
vagrant@precise64:/vagrant/mytest/myrepo.git$ git update-index --refresh
fatal: Unable to write new index file
```
Also, **index.lock is not deleted.**

### Test 3 - gitdll of TortoiseGit 
(git version 1.9.0)
Tracing the source code into **compat/mingw.c**
line 289 : xutftowcs_canonical_path() get the value of var. wpathname
```
D:\Repo\myrepo\.git\index.lock
```
It should be
```
D:\Repo\myrepo.git\.git\index.lock
```

line 294 : _wunlink() try to delete the
file.(```D:\Repo\myrepo\.git\index.lock```)
line 295 : GetLastError() return 3(ERROR_PATH_NOT_FOUND)
(Actually, there is no ```D:\Repo\myrepo\.git``` folder.)





--
View this message in context: 
http://git.661346.n2.nabble.com/git-update-index-not-delete-lock-file-when-using-different-worktree-tp7615300.html
Sent from the git mailing list archive at Nabble.com.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Syncing Git Repositories

2014-07-16 Thread Sajan Parikh
On all my laptops and desktops, I have a directory at /home/sajan/Code 
where all my active projects and repositories live.


/home/sajan/Code/repository1
/home/sajan/Code/repository2
/home/sajan/Code/repository3

...etc...

Up until now I've relied on pushing and pulling to and from my Gitlab 
server to keep my projects in sync across all my laptops and desktops.  
It's worked great.


However, today I decided to add my code folder to my ownCloud server and 
sync it across all my laptops and desktops the same way I do for 
/home/sajan/Documents, /home/sajan/Music, and a few application config 
directories to keep all my devices in sync.


By syncing my code folder and git repositories in this way, do I risk 
borking any repositories?  I'm 99% confident I'm not, since everything 
is in .git/, and there are not external databases or log files that need 
to be updated.  Just making sure though.


I'm only doing this because sometimes I forget to pull changes down from 
my Gitlab server on a different laptop or desktop and start making local 
changes.  Which is fine, I can merge easily, but if everything were 
sync'd automatically when I logged into my computer it would be great.


Another option I thought of would be to write a bash script that 
executed at login and went into each of my repositories and ran git 
pull, but I decided against this because of legitimate non-fast-forward 
merges.


TLDR;

If I sync my repositories across computers using something similar to 
Dropbox, rather than pushing/pulling to and from an central repository, 
am I risking borking any respository?


--
Sajan Parikh




smime.p7s
Description: S/MIME Cryptographic Signature


Re: [PATCH v7 22/31] checkout: support checking out into a new working directory

2014-07-16 Thread Max Kirillov
Hi.

On Sun, Jul 13, 2014 at 11:50:59AM +0700, Nguyễn Thái Ngọc Duy wrote:
 +MULTIPLE CHECKOUT MODE
 +---

This generates incorrect html for me, making all section
until next heading EXAMPLES into a preformatted text. If I
justify the line of dashes to be the exactly same width as
header it starts generating correctly looking html.

I'm not sure which software to refer to. I mostly use Debian
stable. The installed version of asciidocs is 8.6.7-1. I
suppose the line really should be justified because for all
other headings they are.

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