[PATCH] simplified the chain if() statements of install_branch_config() function in branch.c

2014-03-10 Thread Nemina Amarasinghe
Did some simple changing to the chain of if() statements in function
install_branch_config() of branch.c
This was a micro-project for GSOC 2014 


From aebfa60feb643280c89b54e5ab87f9d960cde452 Mon Sep 17 00:00:00 2001
From: Nemina Amarasinghe nemi...@gmail.com
Date: Mon, 10 Mar 2014 13:02:55 +0530
Subject: [PATCH] simplified the chain if() statements of
 install_branch_config() function in branch.c

---
 branch.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/branch.c b/branch.c
index d3b9d49..0304a7a 100644
--- a/branch.c
+++ b/branch.c
@@ -87,7 +87,12 @@ void install_branch_config(int flag, const char *local,
const char *origin, cons
  _(Branch %s set up to track local branch %s 
by rebasing.) :
  _(Branch %s set up to track local branch 
%s.),
  local, shortname);
-   else if (!remote_is_branch  (origin || !origin))
+   else if (!remote_is_branch  origin)
+   printf_ln(rebasing ?
+ _(Branch %s set up to track remote ref %s by 
rebasing.) :
+ _(Branch %s set up to track remote ref %s.),
+ local, remote);
+   else if (!remote_is_branch  !origin)
printf_ln(rebasing ?
  _(Branch %s set up to track remote ref %s by 
rebasing.) :
  _(Branch %s set up to track remote ref %s.),
-- 
1.9.0.152.g6ab4ae2


--
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/RFC] Documentation: Say that submodule clones use a separate gitdirs.

2014-03-10 Thread Henri GEIST
Le dimanche 09 mars 2014 à 19:24 -0400, Andrew Keller a écrit :
 On Mar 7, 2014, at 7:50 PM, Henri GEIST wrote:
  Le vendredi 07 mars 2014 à 15:37 -0800, Junio C Hamano a écrit :
  Henri GEIST geist.he...@laposte.net writes:
  
  This information is technical in nature but has some importance for 
  general users.
  As this kind of clone have a separate gitdir, you will have a surprise if 
  you
  copy past the worktree as the gitdir will not come together.
  
  I am not sure if I understand exactly what you are trying to say.
  Are you saying that you had a submodule at sub/dir in your working
  tree, and then mkdir ../another  cp -R sub/dir ../another did
  not result in a usable Git working tree in ../another directory?
  
  It is almost like complaining that mkdir ../newone  cp -R * ../newone/
  did not result in a usable git repository in ../newone directory and
  honestly speaking, that sounds borderline insane, I'd have to say.
  
  Yes, if a user knows what she is doing, she should be able to make
  something like that work, without running git clone (which is
  probably the way most users would do it).  And yes, it would be good
  to let the user learn from the documentation enough so that she
  knows what she is doing.  But no, I do not think end-user facing
  documentation for git-submodule subcommand is the way to do that.
  
  That is why I suggested repository-layout as potentially a better
  alternative location.
  
  But perhaps I am mis-reading your rationale.
  
  
  
  Let me rephrase my example :
  
  To give one of my project to someone else I have copied it on a USB key.
  By a simple drag and drop with the mouse.
  And I am quite sure I am not alone doing this way.
  
  I have done those kind of things lot of time without any problem.
  But that day 'the_project' happened to be a submodule cloned by
  'git submodule update' then on the USB key the $GIT_DIR of 'the_project'
  was missing.
  
  If 'man git-submodule' have made me aware of the particularities of 
  submodules
  clone I had write in a terminal:
  
  git clone the_project /media/usb/the_project
  
  Or at least I had understand what happened quicker.
  
  I have nothing against also adding something in repository-layout but I am
  pretty sure normal users never read repository-layout as it is not a command
  they use. And it is not mentioned in most tutorials.
 
 How about something like this:
 
 The git directory of a submodule lives inside the git directory of the 
 parent repository instead of within the working directory.
 
 I'm not sure where to put it, though.
 
  - Andrew Keller
 

'git directory' seems ambiguous to me. Maybe we could use 'git metadata'.




signature.asc
Description: This is a digitally signed message part


Re: [PATCH] simplified the chain if() statements of install_branch_config() function in branch.c

2014-03-10 Thread Nemina Amarasinghe
Nemina Amarasinghe neminaa at gmail.com writes:

Sorry for the first patch. Something went wrong. This is the correct one


From aebfa60feb643280c89b54e5ab87f9d960cde452 Mon Sep 17 00:00:00 2001
From: Nemina Amarasinghe nemi...@gmail.com
Date: Mon, 10 Mar 2014 13:02:55 +0530
Subject: [PATCH] simplified the chain if() statements of
 install_brach_config() function in branch.c

---
 branch.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/branch.c b/branch.c
index d3b9d49..0304a7a 100644
--- a/branch.c
+++ b/branch.c
@@ -87,12 +87,7 @@ void install_branch_config(int flag, const char *local,
const char *origin, cons
  _(Branch %s set up to track local branch %s 
by rebasing.) :
  _(Branch %s set up to track local branch 
%s.),
  local, shortname);
-   else if (!remote_is_branch  origin)
-   printf_ln(rebasing ?
- _(Branch %s set up to track remote ref %s by 
rebasing.) :
- _(Branch %s set up to track remote ref %s.),
- local, remote);
-   else if (!remote_is_branch  !origin)
+   else if (!remote_is_branch  (origin || !origin))
printf_ln(rebasing ?
  _(Branch %s set up to track remote ref %s by 
rebasing.) :
  _(Branch %s set up to track remote ref %s.),
-- 
1.9.0.152.g6ab4ae2


--
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 (Mar 2014, #01; Tue, 4)

2014-03-10 Thread Johannes Sixt
Am 3/5/2014 1:10, schrieb Junio C Hamano:
 * nd/gitignore-trailing-whitespace (2014-02-10) 2 commits
  - dir: ignore trailing spaces in exclude patterns
  - dir: warn about trailing spaces in exclude patterns
 
  Warn and then ignore trailing whitespaces in .gitignore files,
  unless they are quoted for fnmatch(3), e.g. path\ .
 
  Will merge to 'next'.

The new test does not pass on Windows. I'll attempt to prepare patches
that amount to work around using FUNNYNAMES, but I'm running out of time now.

-- Hannes
--
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] simplified the chain if() statements of install_branch_config() function in branch.c

2014-03-10 Thread Matthieu Moy
Nemina Amarasinghe nemi...@gmail.com writes:

 Nemina Amarasinghe neminaa at gmail.com writes:

 Sorry for the first patch. Something went wrong. This is the correct one

Please, re-read Documentation/SubmittingPatches. In short, don't inline
patch headers and don't forget the sign-off.

 Subject: [PATCH] simplified the chain if() statements of
  install_brach_config() function in branch.c

Keep the subject line short (ideally 50 characters), and avoid past
tense. We usually use imperative (the patch asks the codebase to
refactor itself = simplify if statements  We usually prefix the
subject line with the place/subsystem where the change is done =
branch.c: simplify if 

 - else if (!remote_is_branch  origin)
 - printf_ln(rebasing ?
 -   _(Branch %s set up to track remote ref %s by 
 rebasing.) :
 -   _(Branch %s set up to track remote ref %s.),
 -   local, remote);
 - else if (!remote_is_branch  !origin)
 + else if (!remote_is_branch  (origin || !origin))

Is it me, or is (origin || !origin) a tautology?

-- 
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/RFC] rebase: new convenient option to edit/reword/delete a single commit

2014-03-10 Thread Michael Haggerty
On 03/09/2014 03:49 AM, Nguyễn Thái Ngọc Duy wrote:
 Prepare the todo list for you to edit/reword/delete the given commit.
 
 Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
 ---
  Allowing multiple actions is a bit too much for my shell skills. I
  don't really need it so I won't push it, but if somebody gives me a
  sketch, I'll try to polish it.
 
  --squash and --fixup would require two commits, making it a bit
  awkward in option handling. Or is the fixup/squash always HEAD?

These commands always squash/fixup the indicated commit with the
previous one.  I think the same approach that you use below should work
for these commands, too.

  Documentation/git-rebase.txt | 11 +++
  git-rebase--interactive.sh   | 17 ++---
  git-rebase.sh| 22 +-
  3 files changed, 46 insertions(+), 4 deletions(-)
 
 diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
 index 2a93c64..becb749 100644
 --- a/Documentation/git-rebase.txt
 +++ b/Documentation/git-rebase.txt
 @@ -13,6 +13,7 @@ SYNOPSIS
  'git rebase' [-i | --interactive] [options] [--exec cmd] [--onto newbase]
   --root [branch]
  'git rebase' --continue | --skip | --abort | --edit-todo
 +'git rebase' [--edit | -E | --reword | -R | --delete | -D ] commit-ish
  
  DESCRIPTION
  ---
 @@ -356,6 +357,16 @@ unless the `--fork-point` option is specified.
   user edit that list before rebasing.  This mode can also be used to
   split commits (see SPLITTING COMMITS below).
  
 +-E=commit::
 +--edit=commit::
 +-R=commit::
 +--reword=commit::
 +-D=commit::
 +--delete=commit::
 + Prepare the todo list to edit or reword or delete the
 + specified commit. Configuration variable `rebase.autostash` is
 + ignored.

If I understand correctly, when one of these options is used, the editor
is not presented to the user at all.  If so, then it is probably
confusing to emphasize the todo list, because the user will never see
it.  How about

Edit, reword, or delete the specified commit, replaying subsequent
commits on top of it (like running `git rebase --interactive
commit^` and then changing the command on the line containing
commit). If conflicts arise when replaying the later commits,
resolve them and run git rebase --continue, as usual. The
configuration variable `rebase.autosquash` is ignored when these
options are used.

 +
  -p::
  --preserve-merges::
   Instead of ignoring merges, try to recreate them.
 diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
 index a1adae8..3ded4c7 100644
 --- a/git-rebase--interactive.sh
 +++ b/git-rebase--interactive.sh
 @@ -1040,9 +1040,20 @@ fi
  has_action $todo ||
   die_abort Nothing to do
  
 -cp $todo $todo.backup
 -git_sequence_editor $todo ||
 - die_abort Could not execute editor
 +if test -n $one_action
 +then
 + commit=`git rev-parse --short $one_commit`
 + sed 1s/pick $commit /$one_action $commit / $todo  $todo.new ||

It wouldn't hurt to anchor this pattern at the beginning of the line.  I
understand that it wouldn't help, either (assuming everything else is
working right), but it makes the intention clearer.

 + die_abort failed to update todo list
 + grep ^$one_action $commit  $todo.new /dev/null ||
 + die_abort expected to find '$one_action $commit' line but did 
 not

The die_aborts above is really an internal consistency check, right?  If
so, maybe it should start with internal error: so that the user
doesn't think that he has done something wrong.

 + mv $todo.new $todo ||
 + die_abort failed to update todo list
 +else
 + cp $todo $todo.backup
 + git_sequence_editor $todo ||
 + die_abort Could not execute editor
 +fi
  
  has_action $todo ||
   die_abort Nothing to do
 diff --git a/git-rebase.sh b/git-rebase.sh
 index 5f6732b..2acffb4 100755
 --- a/git-rebase.sh
 +++ b/git-rebase.sh
 @@ -32,6 +32,9 @@ verify allow pre-rebase hook to run
  rerere-autoupdate  allow rerere to update index with resolved conflicts
  root!  rebase all reachable commits up to the root(s)
  autosquash move commits that begin with squash!/fixup! under -i
 +E,edit=!   generate todo list to edit this commit
 +R,reword=! generate todo list to reword this commit's message
 +D,delete=! generate todo list to delete this commit
  committer-date-is-author-date! passed to 'git am'
  ignore-date!   passed to 'git am'
  whitespace=!   passed to 'git apply'
 @@ -228,6 +231,7 @@ then
  fi
  test -n $type  in_progress=t
  
 +one_action=
  total_argc=$#
  while test $# != 0
  do
 @@ -290,6 +294,7 @@ do
   ;;
   --autostash)
   autostash=true
 + explicit_autosquash=t

Should that be explicit_autostash?

   ;;
   --verbose)
   verbose=t
 @@ -335,6 +340,13 @@ do
   --gpg-sign=*)
   

Re: Potential GSOC microproject idea

2014-03-10 Thread Michael Haggerty
On 03/09/2014 02:54 AM, Kyle J. McKay wrote:
 On Mar 3, 2014, at 23:58, Michael Haggerty wrote:
 list
 regulars should FEEL ENCOURAGED to submit microprojects to add to the
 list.  (Either submit them as a pull request to the GitHub repository
 that contains the text [1] or to the mailing list with CC to me.)
 
 Potential idea for a microproject:
 
 Add a new config setting:
 
   user.allowImplicitIdentity
 Defaults to true.
 If user.name and GIT_COMMITTER_NAME are unset or user.email and
 GIT_COMMITTER_EMAIL and EMAIL are unset, an implicit value is
 substituted for one or both of user.name and user.email.  If
 an automatically generated value is used for both name and email
 a warning Your name and email address were configured
 automatically...
 is displayed.  If set to false, no or never, instead of a warning,
 an error is generated and the operation fails:
 
 *** Please tell me who you are.
 
 Run
 
   git config --global user.email y...@example.com
   git config --global user.name Your Name
 
 to set your account's default identity.
 Omit --global to set the identity only in this repository.
 
 fatal: implicit user identity not allowed
 
 the advice portion can be suppressed by setting
 advice.implicitIdentity to false,
 but not the fatal: implicit user identity not allowed part.
 
 Note that if git config --system --bool user.allowImplicitIdentity
 false is in effect, it should still be possible to clone (ref logs may
 be updated, but they should be allowed to use an implicit identity).  In
 other words user.allowImplicitIdentity=false should only inhibit writing
 any new commit/tag objects that need the current user's name and email
 when it has not been explicitly provided.
 
 I'm not sure how micro this is.  :)  I do think the amount of code
 involved is rather small though.  Support for something like this has
 popped up on the list before.  Perhaps user.allowAutomaticIdentity and
 advice.automaticIdentity would be better config names.

This would be much more work than the other microprojects.  The ones
that I wrote were mostly one- or few-line changes that didn't require
the student to learn a lot of context.  (And most students struggled
mightily with even those.)  So I'm not sure this task is suitable.

Other feedback welcome.  We're pretty much out of microprojects, which
is possibly even worse than having difficult ones.

Michael

-- 
Michael Haggerty
mhag...@alum.mit.edu
http://softwareswirl.blogspot.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


Re: [PATCH] simplified the chain if() statements of install_branch_config() function in branch.c

2014-03-10 Thread David Kastrup
Matthieu Moy matthieu@grenoble-inp.fr writes:

 Nemina Amarasinghe nemi...@gmail.com writes:

 Nemina Amarasinghe neminaa at gmail.com writes:

 Sorry for the first patch. Something went wrong. This is the correct one

 Please, re-read Documentation/SubmittingPatches. In short, don't inline
 patch headers and don't forget the sign-off.

 Subject: [PATCH] simplified the chain if() statements of
  install_brach_config() function in branch.c

 Keep the subject line short (ideally 50 characters), and avoid past
 tense. We usually use imperative (the patch asks the codebase to
 refactor itself = simplify if statements  We usually prefix the
 subject line with the place/subsystem where the change is done =
 branch.c: simplify if 

 -else if (!remote_is_branch  origin)
 -printf_ln(rebasing ?
 - _(Branch %s set up to track remote ref %s by rebasing.) :
 -  _(Branch %s set up to track remote ref %s.),
 -  local, remote);
 -else if (!remote_is_branch  !origin)
 +else if (!remote_is_branch  (origin || !origin))

 Is it me, or is (origin || !origin) a tautology?

Since it _is_ you, that question is a tautology because of its first
part already.  But the second one would be just as good.

-- 
David Kastrup
--
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/RFC] rebase: new convenient option to edit/reword/delete a single commit

2014-03-10 Thread Matthieu Moy
Michael Haggerty mhag...@alum.mit.edu writes:

 @@ -290,6 +294,7 @@ do
  ;;
  --autostash)
  autostash=true
 +explicit_autosquash=t

 Should that be explicit_autostash?

My guess is: no, but it should be below the --autoquash case, not this
one.

-- 
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] simplified the chain if() statements of install_branch_config() function in branch.c

2014-03-10 Thread Nemina Amarasinghe
 
 Nemina Amarasinghe neminaa at gmail.com writes:
 
 Is it me, or is (origin || !origin) a tautology?
 
Thanks for the advices Matthieu. I will go through the documentations again. 
Is there anything wrong with my logic? 
What I wanted to express is
((!remote_is_branch  origin) || (!remote_is_branch || !origin))




--
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] simplified the chain if() statements of install_branch_config() function in branch.c

2014-03-10 Thread Matthieu Moy
Nemina Amarasinghe nemi...@gmail.com writes:

 
 Nemina Amarasinghe neminaa at gmail.com writes:
 
 Is it me, or is (origin || !origin) a tautology?
 
 Thanks for the advices Matthieu. I will go through the documentations again. 
 Is there anything wrong with my logic? 
 What I wanted to express is
 ((!remote_is_branch  origin) || (!remote_is_branch || !origin))

(The second || should be a  in this sentence)

I'm not saying your rewrite is incorrect, but there's no reason to keep
(origin || !origin) in a logical formula.

-- 
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] simplified the chain if() statements of install_branch_config() function in branch.c

2014-03-10 Thread David Kastrup
Nemina Amarasinghe nemi...@gmail.com writes:

 
 Nemina Amarasinghe neminaa at gmail.com writes:
 
 Is it me, or is (origin || !origin) a tautology?
 
 Thanks for the advices Matthieu. I will go through the documentations again. 
 Is there anything wrong with my logic? 
 What I wanted to express is
 ((!remote_is_branch  origin) || (!remote_is_branch || !origin))

Is it?

The above is the same as (!remote_is_branch || !origin).  What you wrote
before is the same as (!remote_is_branch).

Maybe you should try copypaste from the expressions you are trying to
combine to make sure that what you start with makes sense.

-- 
David Kastrup
--
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] submodule : Add --no-separate-git-dir option to add and update command.

2014-03-10 Thread Henri GEIST
Le samedi 08 mars 2014 à 00:00 +0100, Jens Lehmann a écrit :
 Am 06.03.2014 23:20, schrieb Henri GEIST:
  Le jeudi 06 mars 2014 à 21:51 +0100, Jens Lehmann a écrit :
  Am 06.03.2014 21:15, schrieb Henri GEIST:
  Le jeudi 06 mars 2014 à 20:48 +0100, Jens Lehmann a écrit :
  Am 06.03.2014 02:25, schrieb Henri GEIST:
  Wow, that shouldn't even work (as everything inside submodule
  shouldn't be part of the superproject but must be contained in
  the submodule itself). Do the git submodule script and other
  git commands like git status work for you in such setups?
 
  As I stated above it is the purpose of the other patch that I have not 
  already send
  to implement this behavior. And that is why it work.
 
  Ok.
 
  Everything including 'git submodule' and 'git status' work perfectly.
  The intent of this patch is only to permit this for gitlinks. Not for 
  regular files.
 
  But I still believe that this shouldn't be permitted at all,
  no matter if files or submodules are concerned. The pitfalls
  files face in such a scenario are pretty much the same for
  submodules too.
  
  May be you have a good argument for this belief ?
 
 Sure, I stated it further down:
 
  The problem you're creating with your future patch
  is related to the work tree, not the GIT_DIR: subsubmodule
  could also be added to and tracked by submodule (as that is
  completely unaware of subsubmodule already being tracked by
  the superproject). Then you would end up in real trouble, as
  superproject and submodule could have differing SHA-1s
  recorded for subsubmodule. Don't go there, for just the same
  reasons we do not allow that for files.
 
  As for the difference between submodules and regular files
  the only difference is in the meaning.
  Technically directory are just a special kind of file.
  But there day to day use is drastically different of
  the use of files which are not directories.
  I am not against enabling it for files as well.
  I am just unable to imagine a case where it make sens.
 
 It doesn't make sense for both files and submodules.
 
  A possible solution when someone try to do it is to issue a warning.
  We are not able to see any good reason to do this are sure (y/n) ?
 
 No, the only possible solution I see is not to allow that at
 all.
 
  In this case where should the separate gitdir of subsubmodule be placed 
  ?
- In superproject/modules/submodule/subsubmodule ?
- In superproject/submodule/modules/subsubmodule ?
- Depending on the 'git submodule update' command order ?
- Or both ?
 
  It should be placed in .git/modules/submodule/modules/subsubmodule
  of the superproject (assuming the subsubmodule is part of the first
  level submodule). But in your example that would live in
  .git/modules/submodule/subsubmodule (but as mentioned above, I do
  not consider this a valid setup because then two repositories would
  be responsible for the data inside subsubmodule, which will lead to
  lots of trouble).
 
  That is why a had proposed an option '--no-separate-git-dir'
  for 'git submodule add|update' then no repository is responsible for 
  the data
  in subsubmodule except subsubmodule itself.
 
  As I mentioned in my other email, it doesn't matter at all for
  the setup you're describing if the git directory lives under
  .git/modules of the superproject or in a .git directory in the
  submodule. The problem you're creating with your future patch
  is related to the work tree, not the GIT_DIR: subsubmodule
  could also be added to and tracked by submodule (as that is
  completely unaware of subsubmodule already being tracked by
  the superproject). Then you would end up in real trouble, as
  superproject and submodule could have differing SHA-1s
  recorded for subsubmodule. Don't go there, for just the same
  reasons we do not allow that for files.
  
  In fact it mater.
  Because multiples checkout of superproject and submodules in versions
  where subsubmodule is present and not.
  subsubmodule could have been clone one time by submodule and one time
  by superproject.
 
 And each would have a different .git directory. Where is the
 problem with that? Size? Different refs?


The problem is having two gitdir for one worktree.
with the .git file in the worktree pointing sometime on one and sometime on
the other.
 
  And then if they are cloned with --separate-gitdir subsubmodule can
  have two gitdirs in superproject/modules/submodule/subsubmodule and
  in superproject/submodule/modules/subsubmodule.
  Only one is active at a given time but they are two and not synchronized.
 
 But the synchronization is done via the superproject, no?
 

Only lot of careful manual command by the user could keep them synchronize.
But it is big wast of time. For no added value.
It is quicker to make subsubmodule a regular clone without a separate gitdir
then there is nothing needing a synchronization.

  What is the use case you are trying to solve and why can that
  not be handled by adding 

Re: [PATCH] simplified the chain if() statements of install_branch_config() function in branch.c

2014-03-10 Thread Nemina Amarasinghe

  ((!remote_is_branch  origin) || (!remote_is_branch || !origin))
 
 Is it?
 
 The above is the same as (!remote_is_branch || !origin).  What you wrote
 before is the same as (!remote_is_branch).
 
 Maybe you should try copypaste from the expressions you are trying to
 combine to make sure that what you start with makes sense.
 
OMG.. Really sorry for that... that was a silly mistake. 
This is the one..

((!remote_is_branch  origin) || (!remote_is_branch  !origin))



--
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] simplified the chain if() statements of install_branch_config() function in branch.c

2014-03-10 Thread David Kastrup
Nemina Amarasinghe nemi...@gmail.com writes:

  ((!remote_is_branch  origin) || (!remote_is_branch || !origin))
 
 Is it?
 
 The above is the same as (!remote_is_branch || !origin).  What you wrote
 before is the same as (!remote_is_branch).
 
 Maybe you should try copypaste from the expressions you are trying to
 combine to make sure that what you start with makes sense.
 
 OMG.. Really sorry for that... that was a silly mistake. 
 This is the one..

 ((!remote_is_branch  origin) || (!remote_is_branch  !origin))

That is, indeed, perfectly equivalent to (!remote_is_branch).  If you
write

(!remote_is_branch  (origin || !origin))

then you will have people (and possibly also the compiler) loudly
wondering about what you are trying to say here.  The suspicion would be
that either this is a result of a typo or is supposed to be an
annoyingly obtuse replacement for a
/* TODO: treat origin and !origin differently */
kind of comment.

-- 
David Kastrup
--
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: howto to run git without a master branch

2014-03-10 Thread Andreas Schwab
Ilya Bobyr ilya.bo...@gmail.com writes:

 There is a git remote set-head to manipulate HEAD in a remote repository.

This is misleading.  The command does nothing on the remote side, it
only changes the refs/remote namespace in your repository.  The purpose
is to change what branch the ref remote/name resolves to, ie. without
explicit branch name.

(The only command that manipulates the remote repository is git push,
and the plumbing beneath that.  To change HEAD in a remote repository
you need filesystem access to it.)

Andreas.

-- 
Andreas Schwab, sch...@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
And now for something completely different.
--
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


question about: Facebook makes Mercurial faster than Git

2014-03-10 Thread Dennis Luehring

according to these blog posts

http://www.infoq.com/news/2014/01/facebook-scaling-hg
https://code.facebook.com/posts/218678814984400/scaling-mercurial-at-facebook/

mercurial can be faster then git

but i don't found any reply from the git community if it is a real problem
or if there a ongoing (maybe git 2.0) changes to compete better in this case



--
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: question about: Facebook makes Mercurial faster than Git

2014-03-10 Thread David Lang

On Mon, 10 Mar 2014, Dennis Luehring wrote:


according to these blog posts

http://www.infoq.com/news/2014/01/facebook-scaling-hg
https://code.facebook.com/posts/218678814984400/scaling-mercurial-at-facebook/

mercurial can be faster then git

but i don't found any reply from the git community if it is a real problem
or if there a ongoing (maybe git 2.0) changes to compete better in this case


As I understand this, the biggest part of what happened is that Facebook made a 
tweak to mercurial so that when it needs to know what files have changed in 
their massive tree, their version asks their special storage array, while git 
would have to look at it through the filesystem interface (by doing stat calls 
on the directories and files to see if anything has changed)


In other words, unless you have a very high end storage system that can keep 
track of such things for you, the Facebook 'fix' won't help you. And even if it 
does have such a capability, unless you use the same storage system that 
Facebook uses, you would have to port it to your class of device.


Now, in addition to this, they did some other tweaks and changes, but compared 
to this status change, everything else is minor.


David Lang
--
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


Accidentially deleted directory, bug in git clean -d?

2014-03-10 Thread Robin Pedersen
I accidentially deleted a directory using git clean. I would think
this is a bug, but I'm not sure. Was using 1.8.1, but upgraded to
1.9.0 just to see if it was still reproducable, and it was.

Here's a minimal way to reproduce:

$ git init
$ mkdir foo foobar
$ git clean -df foobar
Removing foo/
Removing foobar/
$ ls
$

I expected only foobar to be deleted, but foo was also deleted.

The same thing happens in the opposite case:

$ git init
$ mkdir foo foobar
$ git clean -df foo
Removing foo/
Removing foobar/
$ ls
$

However, it only happens when there is a common prefix in the names:

$ git init
$ mkdir foo bar
$ git clean -df foo
Removing foo/
$ ls
bar
$

In this case, bar was not deleted.

-- 
Best regards,

Robin Pedersen
Software Engineer

SnapTV AS
Jordmor Magdalenes vei 17
N-9519 Kviby.
Norway

rob...@snap.tv
http://www.snap.tv
--
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


[RFC/WIP] Pluggable reference backends

2014-03-10 Thread Michael Haggerty
I have started working on pluggable ref backends.  In this email I
would like to share my plans and solicit feedback.

(This morning I removed this project from the GSoC ideas page, because
it is unfair to ask a student to shoot at a moving target.)

Why?


Currently, the reference- and reflog-handling code in Git is too
coupled to the rest of the system.  There are too many places that
know, for example, the difference between loose and packed refs, or
that loose references are stored as files directly under
$GIT_DIR/refs/heads/, or the locking protocols that have to be adhered
to when managing references.  This tight coupling, in turn, makes it
nearly impossible to experiment with alternate reference storage
schemes.

But there is a lot of potential to use alternate reference storage
schemes to fix some currently-unfixable problems, and to implement
some cool new features.

Unfixable problems
--

The on-disk format that we currently use to store references makes
some problems impossible to fix:

* It is impossible to get a self-consistent snapshot of all references
  at a given moment in time.  This makes it impossible, even in
  principle, to do object pruning in a 100% race-free way.  (Our
  current workaround of not deleting objects that are less than two
  weeks works in most cases but, aside from being ugly, has holes.

* There are awkward filesystem-imposed constraints on reference
  naming, for example:

  * D/F conflicts (I): it is not possible to have branches named
my-feature and my-feature/base at the same time.

  * D/F conflicts (II): it is not possible to have reflogs for
branches named my-feature and my-feature/base at the same
time.  This leads to the problem that it is not, in general,
possible to retain reflogs for branches that have been deleted.

  * There are additional constraints on reference names depending on
the filesystem used to store them.  For example, a Git repository
on a case-insensitive filesystem fails in confusing ways if there
are two loose references whose names differ only in case; however,
packed references differing in case might work for a while.  Also,
reference names that include Unicode characters can have their
normalization form changed if they are written on Mac OS.

* The packed-refs file has to be rewritten whenever a packed reference
  is deleted.  It might be nice to write 0{40} to a loose reference
  file to indicate that the reference has been deleted, but that would
  open the way for more D/F conflicts.)

Wild new ideas
--

So, I would like to reorganize the Git code to allow pluggable
reference backends.  If we had this, we could try out ideas like

* Retain the idea of loose/packed references, but encode loose
  reference names using a portable naming scheme before storing them
  to the filesystem; maybe something like

  refs/heads/Foo.42 - refs.dir/heads.dir/%46oo%2e42
  logs/refs/heads/Foo.42 - refs.dir/heads.dir/%46oo%2e42.log

  Yes, it looks uglier.  But users shouldn't be looking in these
  directories anyway.  This single change would prevent D/F conflicts,
  allow a reference to be deleted by writing 0{40} to its loose
  reference file, allow reflogs to be kept for deleted refs, and
  remove the problem of filesystem-dependent naming constraints.

* Store references in a SQLite database, to get correct transaction
  handling.

* Store references directly in the Git object database.

* Implement repository groups that share a common object database
  and also a common reference store.  Each repository in a group would
  get a sub-namespace in the shared database, and store its references
  in names like refs/member/$MEMBERID/refs/heads/  The member
  repos would act like restricted views of the shared database.  This
  would be like a combination between alternates (with lowered risk of
  corruption) and gitnamespaces(7) (but usable for all git commands).

* Reference transactions that can be used across multiple Git
  commands.  Imagine,

  export GIT_TRANSACTION=$(git transaction begin)
  trap 'git transaction rollback' ERR
  git foo ...
  git bar ...
  git baz ...
  if ! git transaction commit
  then
  # Transaction failed; all references rolled back
  else
  # Transaction succeeded; all references updated atomically
  fi
  trap '' ERR
  unset GIT_TRANSACTION

  The GIT_TRANSACTION environment variable would tell git to read
  from the usual references, overridden with any reference changes
  that have occurred during the transaction, but write any changes
  (including both old and new values) to the transaction.  The command
  git transaction commit would verify that the old values listed in
  the transaction still agree with the current values, and then make
  all of the changes atomically.

  Such transactions could also be broadcast to mirrors when they are
  committed to keep multiple Git 

Re: question about: Facebook makes Mercurial faster than Git

2014-03-10 Thread demerphq
On 10 March 2014 11:07, Dennis Luehring dl.so...@gmx.net wrote:
 according to these blog posts

 http://www.infoq.com/news/2014/01/facebook-scaling-hg
 https://code.facebook.com/posts/218678814984400/scaling-mercurial-at-facebook/

 mercurial can be faster then git

 but i don't found any reply from the git community if it is a real problem
 or if there a ongoing (maybe git 2.0) changes to compete better in this case

They mailed the list about performance issues in git. From what I saw
there was relatively little feedback.

I had the impression, and I would not be surprised if they had the
impression that the git development community is relatively
unconcerned about performance issues on larger repositories.

There have been other reports, which are difficult to keep track of
without a bug tracking system, but the ones I know of are:

Poor performance of git status with large number of excluded files and
large repositories.
Poor performance, and breakage, on repositories with very large
numbers of files in them. (Rebase for instance will break if you
rebase a commit that contains a *lot* of files.)
Poor performance in protocol layer (and other places) with repos with
large numbers of refs. (Maybe this is fixed, not sure.)

cheers,
Yves




-- 
perl -Mre=debug -e /just|another|perl|hacker/
--
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: question about: Facebook makes Mercurial faster than Git

2014-03-10 Thread Dennis Luehring

Am 10.03.2014 12:28, schrieb demerphq:

I had the impression, and I would not be surprised if they had the
impression that the git development community is relatively
unconcerned about performance issues on larger repositories.


so the question is if the git community is interested in beeing 
competive in such
large scale scenarios - something what mercurial seems to be now out of 
the box



--
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: [RFC/WIP] Pluggable reference backends

2014-03-10 Thread Johan Herland
On Mon, Mar 10, 2014 at 12:00 PM, Michael Haggerty mhag...@alum.mit.edu wrote:
 I have started working on pluggable ref backends.  In this email I
 would like to share my plans and solicit feedback.

No comments or useful feedback yet, except that I enthusiastically
approve of the objective and the plan you have for how to get there.


...Johan

-- 
Johan Herland, jo...@herland.net
www.herland.net
--
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: question about: Facebook makes Mercurial faster than Git

2014-03-10 Thread Johan Herland
On Mon, Mar 10, 2014 at 12:42 PM, Dennis Luehring dl.so...@gmx.net wrote:
 Am 10.03.2014 12:28, schrieb demerphq:

 I had the impression, and I would not be surprised if they had the
 impression that the git development community is relatively
 unconcerned about performance issues on larger repositories.

 so the question is if the git community is interested in beeing competive in
 such large scale scenarios - something what mercurial seems to be now out
 of the box

AFAIK, David Lang's comment is not far off the mark. Facebook has made
a tool called Watchman (https://github.com/facebook/watchman) that
watches your work tree (i.e. wrapping inotify on Linux) and triggers
various commands when files within are changed (e.g. do an auto-build
whenever a file in your project changes). Since this tool will
discover when files change, they have adjusted Mercurial to discover
changes by querying Watchman instead of stat-ing the entire work tree.

AFAICS, this is basically a tradeoff between the time it takes to stat
your work tree and the overhead/administrivia of running a daemon to
monitor the work tree. It seems Facebook has organized their code and
infrastructure in a way that makes the latter approach worthwhile for
them, and has contributed their solution back to Mercurial.

It should be possible to teach Git to do similar things, and IINM
there are (and have previously been) several attempts to do similar
things in Git, e.g.:

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

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

I haven't looked closely at these attempts (it is not my scratch to
itch), and I don't know if/how they would work on top of Watchman, but
in principle I don't see why Git shouldn't be able to leverage
Watchman the same way Mercurial does.


...Johan

-- 
Johan Herland, jo...@herland.net
www.herland.net
--
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/26] refs.h: Rename the action_on_err constants

2014-03-10 Thread Michael Haggerty
Given that these constants are only being used when updating
references, it is inappropriate to give them such generic names as
DIE_ON_ERR.  So prefix their names with UPDATE_REFS_.

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 builtin/checkout.c |  2 +-
 builtin/clone.c|  9 +
 builtin/merge.c|  6 +++---
 builtin/notes.c|  6 +++---
 builtin/reset.c|  6 --
 builtin/update-ref.c   |  5 +++--
 contrib/examples/builtin-fetch--tool.c |  3 ++-
 notes-cache.c  |  2 +-
 notes-utils.c  |  3 ++-
 refs.c | 18 +-
 refs.h |  9 +++--
 11 files changed, 40 insertions(+), 29 deletions(-)

diff --git a/builtin/checkout.c b/builtin/checkout.c
index ada51fa..f79b222 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -624,7 +624,7 @@ static void update_refs_for_switch(const struct 
checkout_opts *opts,
/* Nothing to do. */
} else if (opts-force_detach || !new-path) {  /* No longer on any 
branch. */
update_ref(msg.buf, HEAD, new-commit-object.sha1, NULL,
-  REF_NODEREF, DIE_ON_ERR);
+  REF_NODEREF, UPDATE_REFS_DIE_ON_ERR);
if (!opts-quiet) {
if (old-path  advice_detached_head)
detach_advice(new-name);
diff --git a/builtin/clone.c b/builtin/clone.c
index 43e772c..af3b86f 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -521,7 +521,7 @@ static void write_followtags(const struct ref *refs, const 
char *msg)
if (!has_sha1_file(ref-old_sha1))
continue;
update_ref(msg, ref-name, ref-old_sha1,
-  NULL, 0, DIE_ON_ERR);
+  NULL, 0, UPDATE_REFS_DIE_ON_ERR);
}
 }
 
@@ -589,14 +589,15 @@ static void update_head(const struct ref *our, const 
struct ref *remote,
create_symref(HEAD, our-name, NULL);
if (!option_bare) {
const char *head = skip_prefix(our-name, 
refs/heads/);
-   update_ref(msg, HEAD, our-old_sha1, NULL, 0, 
DIE_ON_ERR);
+   update_ref(msg, HEAD, our-old_sha1, NULL, 0,
+  UPDATE_REFS_DIE_ON_ERR);
install_branch_config(0, head, option_origin, 
our-name);
}
} else if (our) {
struct commit *c = lookup_commit_reference(our-old_sha1);
/* --branch specifies a non-branch (i.e. tags), detach HEAD */
update_ref(msg, HEAD, c-object.sha1,
-  NULL, REF_NODEREF, DIE_ON_ERR);
+  NULL, REF_NODEREF, UPDATE_REFS_DIE_ON_ERR);
} else if (remote) {
/*
 * We know remote HEAD points to a non-branch, or
@@ -604,7 +605,7 @@ static void update_head(const struct ref *our, const struct 
ref *remote,
 * Detach HEAD in all these cases.
 */
update_ref(msg, HEAD, remote-old_sha1,
-  NULL, REF_NODEREF, DIE_ON_ERR);
+  NULL, REF_NODEREF, UPDATE_REFS_DIE_ON_ERR);
}
 }
 
diff --git a/builtin/merge.c b/builtin/merge.c
index f0cf120..a4c3b17 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -398,7 +398,7 @@ static void finish(struct commit *head_commit,
const char *argv_gc_auto[] = { gc, --auto, NULL };
update_ref(reflog_message.buf, HEAD,
new_head, head, 0,
-   DIE_ON_ERR);
+   UPDATE_REFS_DIE_ON_ERR);
/*
 * We ignore errors in 'gc --auto', since the
 * user should see them.
@@ -1222,7 +1222,7 @@ int cmd_merge(int argc, const char **argv, const char 
*prefix)
die(_(%s - not something we can merge), argv[0]);
read_empty(remote_head-object.sha1, 0);
update_ref(initial pull, HEAD, remote_head-object.sha1,
-  NULL, 0, DIE_ON_ERR);
+  NULL, 0, UPDATE_REFS_DIE_ON_ERR);
goto done;
} else {
struct strbuf merge_names = STRBUF_INIT;
@@ -1339,7 +1339,7 @@ int cmd_merge(int argc, const char **argv, const char 
*prefix)
}
 
update_ref(updating ORIG_HEAD, ORIG_HEAD, head_commit-object.sha1,
-  NULL, 0, DIE_ON_ERR);
+  NULL, 0, UPDATE_REFS_DIE_ON_ERR);
 
if (remoteheads  !common)
; /* No common ancestors found. We need a real merge. */
diff --git a/builtin/notes.c b/builtin/notes.c

[PATCH 04/26] parse_arg(): Really test that argument is properly terminated

2014-03-10 Thread Michael Haggerty
Add a docstring to the function incorporating the comments that were
formerly within the function plus some added information.  Test that
the argument is properly terminated by either whitespace or a NUL
character, even if it is quoted, to be consistent with the non-quoted
case.  Adjust the tests to expect the new error message.

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 builtin/update-ref.c  | 20 +++-
 t/t1400-update-ref.sh |  4 ++--
 2 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/builtin/update-ref.c b/builtin/update-ref.c
index 1292cfe..02b5f95 100644
--- a/builtin/update-ref.c
+++ b/builtin/update-ref.c
@@ -62,16 +62,26 @@ static void update_store_old_sha1(struct ref_update *update,
update-have_old = *oldvalue || line_termination;
 }
 
+/*
+ * Parse one whitespace- or NUL-terminated, possibly C-quoted argument
+ * and append the result to arg.  Return a pointer to the terminator.
+ * Die if there is an error in how the argument is C-quoted.  This
+ * function is only used if not -z.
+ */
 static const char *parse_arg(const char *next, struct strbuf *arg)
 {
-   /* Parse SP-terminated, possibly C-quoted argument */
-   if (*next != '')
+   if (*next == '') {
+   const char *orig = next;
+
+   if (unquote_c_style(arg, next, next))
+   die(badly quoted argument: %s, orig);
+   if (*next  !isspace(*next))
+   die(unexpected character after quoted argument: %s, 
orig);
+   } else {
while (*next  !isspace(*next))
strbuf_addch(arg, *next++);
-   else if (unquote_c_style(arg, next, next))
-   die(badly quoted argument: %s, next);
+   }
 
-   /* Return position after the argument */
return next;
 }
 
diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh
index e2f1dfa..5836842 100755
--- a/t/t1400-update-ref.sh
+++ b/t/t1400-update-ref.sh
@@ -356,10 +356,10 @@ test_expect_success 'stdin fails on badly quoted input' '
grep fatal: badly quoted argument: \\\master err
 '
 
-test_expect_success 'stdin fails on arguments not separated by space' '
+test_expect_success 'stdin fails on junk after quoted argument' '
echo create \$a\master stdin 
test_must_fail git update-ref --stdin stdin 2err 
-   grep fatal: expected SP but got: master err
+   grep fatal: unexpected character after quoted argument: 
\\\$a\\\master err
 '
 
 test_expect_success 'stdin fails create with no ref' '
-- 
1.9.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


[PATCH 01/26] t1400: Fix name and expected result of one test

2014-03-10 Thread Michael Haggerty
The test

stdin -z create ref fails with zero new value

actually passes an empty new value, not a zero new value.  So rename
the test s/zero/empty/, and change the expected error from

fatal: create $c given zero new value

to

fatal: create $c missing newvalue

Of course, this makes the test fail now, so mark it
test_expect_failure.  The failure will be fixed later in this patch
series.

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 t/t1400-update-ref.sh | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh
index 6ffd82f..fa927d2 100755
--- a/t/t1400-update-ref.sh
+++ b/t/t1400-update-ref.sh
@@ -827,10 +827,10 @@ test_expect_success 'stdin -z create ref fails with bad 
new value' '
test_must_fail git rev-parse --verify -q $c
 '
 
-test_expect_success 'stdin -z create ref fails with zero new value' '
+test_expect_failure 'stdin -z create ref fails with empty new value' '
printf $F create $c  stdin 
test_must_fail git update-ref -z --stdin stdin 2err 
-   grep fatal: create $c given zero new value err 
+   grep fatal: create $c missing newvalue err 
test_must_fail git rev-parse --verify -q $c
 '
 
-- 
1.9.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


[PATCH 00/26] Clean up update-refs --stdin and implement ref_transaction

2014-03-10 Thread Michael Haggerty
I just sent an email to the list [1] describing how I want to
decouple reference-handling code from the rest of Git, and implement
pluggable reference storage backends.  This patch series is the first
movement in that direction.

update_refs() and update-ref --stdin implement the beginning of
transactions for git references, by allowing a group of reference
changes to be done in an all-or-nothing fashion.  The main point of
this patch series is to increase the abstraction level of the API for
dealing with reference transactions, by moving the handling of the
transaction to refs.c.  The new API for dealing with reference
transactions is

ref_transaction *transaction = create_ref_transaction();
queue_create_ref(transaction, refname, new_sha1, ...);
queue_update_ref(transaction, refname, new_sha1, old_sha1, ...);
queue_delete_ref(transaction, refname, old_sha1, ...);
...
if (commit_ref_transaction(transaction, msg, ...))
die(...);

When implementing this I found a number of minor problems in the
implementation of git update-ref --stdin, not to mention that it
used struct ref_update all the way up and down its parser call
stack.  So most of the commits in this series are actually cleanups in
builtin/update-ref.c.  I also spend some time making the error
messages emitted by that command more uniform.

Then, in just a couple of commits, the ref_transaction abstraction is
introduced, update-ref is changed to use it, and update_refs() is
removed from the refs API (it was only used by this one caller).

Finally, now that refs.c owns the data structures for dealing with
transactions, it is possible to make a few simplifications.  More
changes in this neighborhood will be coming in future patches.

[1] http://article.gmane.org/gmane.comp.version-control.git/243726

Michael Haggerty (26):
  t1400: Fix name and expected result of one test
  t1400: Provide sensible input to the command
  t1400: Pass a legitimate newvalue to update command
  parse_arg(): Really test that argument is properly terminated
  t1400: Add some more tests involving quoted arguments
  refs.h: Rename the action_on_err constants
  update_refs(): Fix constness
  update-ref --stdin: Read the whole input at once
  parse_cmd_verify(): Copy old_sha1 instead of evaluating oldvalue
twice
  update-ref.c: Extract a new function, parse_refname()
  update-ref --stdin: Improve error messages for invalid values
  update-ref --stdin: Make error messages more consistent
  update-ref --stdin: Simplify error messages for missing oldvalues
  update-ref.c: Extract a new function, parse_next_sha1()
  update-ref --stdin: Improve the error message for unexpected EOF
  update-ref --stdin: Harmonize error messages
  refs: Add a concept of a reference transaction
  update-ref --stdin: Reimplement using reference transactions
  refs: Remove API function update_refs()
  struct ref_update: Rename field ref_name to refname
  struct ref_update: Store refname as a FLEX_ARRAY.
  commit_ref_transaction(): Introduce temporary variables
  struct ref_update: Add a lock member
  struct ref_update: Add type field
  commit_ref_transaction(): Also free the ref_transaction
  commit_ref_transaction(): Work with transaction-updates in place

 builtin/checkout.c |   2 +-
 builtin/clone.c|   9 +-
 builtin/merge.c|   6 +-
 builtin/notes.c|   6 +-
 builtin/reset.c|   6 +-
 builtin/update-ref.c   | 402 +++--
 contrib/examples/builtin-fetch--tool.c |   3 +-
 notes-cache.c  |   2 +-
 notes-utils.c  |   3 +-
 refs.c | 184 +++
 refs.h |  93 ++--
 t/t1400-update-ref.sh  |  86 ---
 12 files changed, 524 insertions(+), 278 deletions(-)

-- 
1.9.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


[PATCH 19/26] refs: Remove API function update_refs()

2014-03-10 Thread Michael Haggerty
This should be done via reference transactions now.  This also means
that struct ref_update can become private.

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 refs.c | 31 ---
 refs.h | 20 
 2 files changed, 20 insertions(+), 31 deletions(-)

diff --git a/refs.c b/refs.c
index 54260ce..91af0a0 100644
--- a/refs.c
+++ b/refs.c
@@ -3267,6 +3267,20 @@ static int update_ref_write(const char *action, const 
char *refname,
return 0;
 }
 
+/**
+ * Information needed for a single ref update.  Set new_sha1 to the
+ * new value or to zero to delete the ref.  To check the old value
+ * while locking the ref, set have_old to 1 and set old_sha1 to the
+ * value or to zero to ensure the ref does not exist before update.
+ */
+struct ref_update {
+   const char *ref_name;
+   unsigned char new_sha1[20];
+   unsigned char old_sha1[20];
+   int flags; /* REF_NODEREF? */
+   int have_old; /* 1 if old_sha1 is valid, 0 otherwise */
+};
+
 /*
  * Data structure for holding a reference transaction, which can
  * consist of checks and updates to multiple references, carried out
@@ -3385,16 +3399,17 @@ static int ref_update_reject_duplicates(struct 
ref_update **updates, int n,
return 0;
 }
 
-int update_refs(const char *action, struct ref_update * const *updates_orig,
-   int n, enum action_on_err onerr)
+int commit_ref_transaction(struct ref_transaction *transaction,
+  const char *msg, enum action_on_err onerr)
 {
int ret = 0, delnum = 0, i;
struct ref_update **updates;
int *types;
struct ref_lock **locks;
const char **delnames;
+   int n = transaction-nr;
 
-   if (!updates_orig || !n)
+   if (!n)
return 0;
 
/* Allocate work space */
@@ -3404,7 +3419,7 @@ int update_refs(const char *action, struct ref_update * 
const *updates_orig,
delnames = xmalloc(sizeof(*delnames) * n);
 
/* Copy, sort, and reject duplicate refs */
-   memcpy(updates, updates_orig, sizeof(*updates) * n);
+   memcpy(updates, transaction-updates, sizeof(*updates) * n);
qsort(updates, n, sizeof(*updates), ref_update_compare);
ret = ref_update_reject_duplicates(updates, n, onerr);
if (ret)
@@ -3426,7 +3441,7 @@ int update_refs(const char *action, struct ref_update * 
const *updates_orig,
/* Perform updates first so live commits remain referenced */
for (i = 0; i  n; i++)
if (!is_null_sha1(updates[i]-new_sha1)) {
-   ret = update_ref_write(action,
+   ret = update_ref_write(msg,
   updates[i]-ref_name,
   updates[i]-new_sha1,
   locks[i], onerr);
@@ -3457,12 +3472,6 @@ cleanup:
return ret;
 }
 
-int commit_ref_transaction(struct ref_transaction *transaction,
-  const char *msg, enum action_on_err onerr)
-{
-   return update_refs(msg, transaction-updates, transaction-nr, onerr);
-}
-
 char *shorten_unambiguous_ref(const char *refname, int strict)
 {
int i;
diff --git a/refs.h b/refs.h
index 2848fb7..b1f8b74 100644
--- a/refs.h
+++ b/refs.h
@@ -10,20 +10,6 @@ struct ref_lock {
int force_write;
 };
 
-/**
- * Information needed for a single ref update.  Set new_sha1 to the
- * new value or to zero to delete the ref.  To check the old value
- * while locking the ref, set have_old to 1 and set old_sha1 to the
- * value or to zero to ensure the ref does not exist before update.
- */
-struct ref_update {
-   const char *ref_name;
-   unsigned char new_sha1[20];
-   unsigned char old_sha1[20];
-   int flags; /* REF_NODEREF? */
-   int have_old; /* 1 if old_sha1 is valid, 0 otherwise */
-};
-
 struct ref_transaction;
 
 /*
@@ -288,12 +274,6 @@ int update_ref(const char *action, const char *refname,
const unsigned char *sha1, const unsigned char *oldval,
int flags, enum action_on_err onerr);
 
-/**
- * Lock all refs and then perform all modifications.
- */
-int update_refs(const char *action, struct ref_update * const *updates,
-   int n, enum action_on_err onerr);
-
 extern int parse_hide_refs_config(const char *var, const char *value, const 
char *);
 extern int ref_is_hidden(const char *);
 
-- 
1.9.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


[PATCH 18/26] update-ref --stdin: Reimplement using reference transactions

2014-03-10 Thread Michael Haggerty
This change is mostly clerical: the parse_cmd_*() functions need to
use local variables rather than a struct ref_update to collect the
arguments needed for each update, and then call queue_*_ref() to queue
the change rather than building up the list of changes at the caller
side.

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 builtin/update-ref.c | 142 +++
 1 file changed, 76 insertions(+), 66 deletions(-)

diff --git a/builtin/update-ref.c b/builtin/update-ref.c
index ac41635..ffed061 100644
--- a/builtin/update-ref.c
+++ b/builtin/update-ref.c
@@ -12,29 +12,11 @@ static const char * const git_update_ref_usage[] = {
NULL
 };
 
-static int updates_alloc;
-static int updates_count;
-static struct ref_update **updates;
+static struct ref_transaction *transaction;
 
 static char line_termination = '\n';
 static int update_flags;
 
-static struct ref_update *update_alloc(void)
-{
-   struct ref_update *update;
-
-   /* Allocate and zero-init a struct ref_update */
-   update = xcalloc(1, sizeof(*update));
-   ALLOC_GROW(updates, updates_count + 1, updates_alloc);
-   updates[updates_count++] = update;
-
-   /* Store and reset accumulated options */
-   update-flags = update_flags;
-   update_flags = 0;
-
-   return update;
-}
-
 /*
  * Parse one whitespace- or NUL-terminated, possibly C-quoted argument
  * and append the result to arg.  Return a pointer to the terminator.
@@ -174,95 +156,118 @@ static int parse_next_sha1(struct strbuf *input, const 
char **next,
 
 static const char *parse_cmd_update(struct strbuf *input, const char *next)
 {
-   struct ref_update *update;
-
-   update = update_alloc();
+   char *refname;
+   unsigned char new_sha1[20];
+   unsigned char old_sha1[20];
+   int have_old;
 
-   update-ref_name = parse_refname(input, next);
-   if (!update-ref_name)
+   refname = parse_refname(input, next);
+   if (!refname)
die(update: missing ref);
 
-   if (parse_next_sha1(input, next, update-new_sha1,
-   update, update-ref_name, 0))
-   die(update %s: missing newvalue, update-ref_name);
+   if (parse_next_sha1(input, next, new_sha1,
+   update, refname, 0))
+   die(update %s: missing newvalue, refname);
 
-   update-have_old = !parse_next_sha1(input, next, update-old_sha1,
-   update, update-ref_name, 1);
+   have_old = !parse_next_sha1(input, next, old_sha1,
+   update, refname, 1);
 
if (*next != line_termination)
-   die(update %s: extra input: %s, update-ref_name, next);
+   die(update %s: extra input: %s, refname, next);
+
+   queue_update_ref(transaction, refname, new_sha1, old_sha1,
+update_flags, have_old);
+
+   update_flags = 0;
+   free(refname);
 
return next;
 }
 
 static const char *parse_cmd_create(struct strbuf *input, const char *next)
 {
-   struct ref_update *update;
-
-   update = update_alloc();
+   char *refname;
+   unsigned char new_sha1[20];
 
-   update-ref_name = parse_refname(input, next);
-   if (!update-ref_name)
+   refname = parse_refname(input, next);
+   if (!refname)
die(create: missing ref);
 
-   if (parse_next_sha1(input, next, update-new_sha1,
-   create, update-ref_name, 0))
-   die(create %s: missing newvalue, update-ref_name);
+   if (parse_next_sha1(input, next, new_sha1,
+   create, refname, 0))
+   die(create %s: missing newvalue, refname);
 
-   if (is_null_sha1(update-new_sha1))
-   die(create %s: zero newvalue, update-ref_name);
+   if (is_null_sha1(new_sha1))
+   die(create %s: zero newvalue, refname);
 
if (*next != line_termination)
-   die(create %s: extra input: %s, update-ref_name, next);
+   die(create %s: extra input: %s, refname, next);
+
+   queue_create_ref(transaction, refname, new_sha1, update_flags);
+
+   update_flags = 0;
+   free(refname);
 
return next;
 }
 
 static const char *parse_cmd_delete(struct strbuf *input, const char *next)
 {
-   struct ref_update *update;
+   char *refname;
+   unsigned char old_sha1[20];
+   int have_old;
 
-   update = update_alloc();
-
-   update-ref_name = parse_refname(input, next);
-   if (!update-ref_name)
+   refname = parse_refname(input, next);
+   if (!refname)
die(delete: missing ref);
 
-   if (parse_next_sha1(input, next, update-old_sha1,
-   delete, update-ref_name, 1)) {
-   update-have_old = 0;
+   if (parse_next_sha1(input, next, old_sha1, delete, refname, 1)) {
+   have_old = 

[PATCH 11/26] update-ref --stdin: Improve error messages for invalid values

2014-03-10 Thread Michael Haggerty
If an invalid value is passed to update-ref --stdin as oldvalue or
newvalue, include the command and the name of the reference at the
beginning of the error message.  Update the tests accordingly.

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 builtin/update-ref.c  | 24 +---
 t/t1400-update-ref.sh |  8 
 2 files changed, 17 insertions(+), 15 deletions(-)

diff --git a/builtin/update-ref.c b/builtin/update-ref.c
index 0dc2061..13a884a 100644
--- a/builtin/update-ref.c
+++ b/builtin/update-ref.c
@@ -35,20 +35,22 @@ static struct ref_update *update_alloc(void)
return update;
 }
 
-static void update_store_new_sha1(struct ref_update *update,
+static void update_store_new_sha1(const char *command,
+ struct ref_update *update,
  const char *newvalue)
 {
if (*newvalue  get_sha1(newvalue, update-new_sha1))
-   die(invalid new value for ref %s: %s,
-   update-ref_name, newvalue);
+   die(%s %s: invalid new value: %s,
+   command, update-ref_name, newvalue);
 }
 
-static void update_store_old_sha1(struct ref_update *update,
+static void update_store_old_sha1(const char *command,
+ struct ref_update *update,
  const char *oldvalue)
 {
if (*oldvalue  get_sha1(oldvalue, update-old_sha1))
-   die(invalid old value for ref %s: %s,
-   update-ref_name, oldvalue);
+   die(%s %s: invalid old value: %s,
+   command, update-ref_name, oldvalue);
 
/* We have an old value if non-empty, or if empty without -z */
update-have_old = *oldvalue || line_termination;
@@ -165,12 +167,12 @@ static const char *parse_cmd_update(struct strbuf *input, 
const char *next)
die(update line missing ref);
 
if (!parse_next_arg(input, next, newvalue))
-   update_store_new_sha1(update, newvalue.buf);
+   update_store_new_sha1(update, update, newvalue.buf);
else
die(update %s missing newvalue, update-ref_name);
 
if (!parse_next_arg(input, next, oldvalue)) {
-   update_store_old_sha1(update, oldvalue.buf);
+   update_store_old_sha1(update, update, oldvalue.buf);
if (*next != line_termination)
die(update %s has extra input: %s, update-ref_name, 
next);
} else if (!line_termination)
@@ -191,7 +193,7 @@ static const char *parse_cmd_create(struct strbuf *input, 
const char *next)
die(create line missing ref);
 
if (!parse_next_arg(input, next, newvalue))
-   update_store_new_sha1(update, newvalue.buf);
+   update_store_new_sha1(create, update, newvalue.buf);
else
die(create %s missing newvalue, update-ref_name);
 
@@ -216,7 +218,7 @@ static const char *parse_cmd_delete(struct strbuf *input, 
const char *next)
die(delete line missing ref);
 
if (!parse_next_arg(input, next, oldvalue)) {
-   update_store_old_sha1(update, oldvalue.buf);
+   update_store_old_sha1(delete, update, oldvalue.buf);
if (update-have_old  is_null_sha1(update-old_sha1))
die(delete %s given zero old value, update-ref_name);
} else if (!line_termination)
@@ -240,7 +242,7 @@ static const char *parse_cmd_verify(struct strbuf *input, 
const char *next)
die(verify line missing ref);
 
if (!parse_next_arg(input, next, value)) {
-   update_store_old_sha1(update, value.buf);
+   update_store_old_sha1(verify, update, value.buf);
hashcpy(update-new_sha1, update-old_sha1);
} else if (!line_termination)
die(verify %s missing [oldvalue] NUL, update-ref_name);
diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh
index 627aaaf..c5be870 100755
--- a/t/t1400-update-ref.sh
+++ b/t/t1400-update-ref.sh
@@ -518,14 +518,14 @@ test_expect_success 'stdin update ref fails with wrong 
old value' '
 test_expect_success 'stdin update ref fails with bad old value' '
echo update $c $m does-not-exist stdin 
test_must_fail git update-ref --stdin stdin 2err 
-   grep fatal: invalid old value for ref $c: does-not-exist err 
+   grep fatal: update $c: invalid old value: does-not-exist err 
test_must_fail git rev-parse --verify -q $c
 '
 
 test_expect_success 'stdin create ref fails with bad new value' '
echo create $c does-not-exist stdin 
test_must_fail git update-ref --stdin stdin 2err 
-   grep fatal: invalid new value for ref $c: does-not-exist err 
+   grep fatal: create $c: invalid new value: does-not-exist err 
test_must_fail git rev-parse --verify -q $c
 '
 
@@ -840,14 +840,14 @@ test_expect_success 'stdin -z update ref fails 

[PATCH 08/26] update-ref --stdin: Read the whole input at once

2014-03-10 Thread Michael Haggerty
Decouple the parsing code from the input source (the old parsing code
had to read new data even in the middle of commands).  This might also
be a tad faster, but that is inconsequential.  Add docstrings for the
parsing functions.

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 builtin/update-ref.c | 170 ---
 1 file changed, 108 insertions(+), 62 deletions(-)

diff --git a/builtin/update-ref.c b/builtin/update-ref.c
index a8a68e8..5f197fe 100644
--- a/builtin/update-ref.c
+++ b/builtin/update-ref.c
@@ -85,44 +85,70 @@ static const char *parse_arg(const char *next, struct 
strbuf *arg)
return next;
 }
 
-static const char *parse_first_arg(const char *next, struct strbuf *arg)
+/*
+ * Parse the argument immediately after command SP.  If not -z, then
+ * handle C-quoting.  Write the argument to arg.  Set *next to point
+ * at the character that terminates the argument.  Die if C-quoting is
+ * malformed.
+ */
+static void parse_first_arg(struct strbuf *input, const char **next,
+   struct strbuf *arg)
 {
-   /* Parse argument immediately after command SP */
strbuf_reset(arg);
if (line_termination) {
/* Without -z, use the next argument */
-   next = parse_arg(next, arg);
+   *next = parse_arg(*next, arg);
} else {
-   /* With -z, use rest of first NUL-terminated line */
-   strbuf_addstr(arg, next);
-   next = next + arg-len;
+   /* With -z, use everything up to the next NUL */
+   strbuf_addstr(arg, *next);
+   *next += arg-len;
}
-   return next;
 }
 
-static const char *parse_next_arg(const char *next, struct strbuf *arg)
+/*
+ * Parse a SP/NUL separator followed by the next SP- or NUL-terminated
+ * argument, if any.  If there is an argument, write it to arg, set
+ * *next to point at the character terminating the argument, and
+ * return 0.  If there is no argument at all (not even the empty
+ * string), return a non-zero result and leave *next unchanged.
+ */
+static int parse_next_arg(struct strbuf *input, const char **next,
+ struct strbuf *arg)
 {
-   /* Parse next SP-terminated or NUL-terminated argument, if any */
strbuf_reset(arg);
if (line_termination) {
/* Without -z, consume SP and use next argument */
-   if (!*next)
-   return NULL;
-   if (*next != ' ')
-   die(expected SP but got: %s, next);
-   next = parse_arg(next + 1, arg);
+   if (!**next || **next == line_termination)
+   return -1;
+   if (**next != ' ')
+   die(expected SP but got: %s, *next);
+   (*next)++;
+   *next = parse_arg(*next, arg);
} else {
/* With -z, read the next NUL-terminated line */
-   if (*next)
-   die(expected NUL but got: %s, next);
-   if (strbuf_getline(arg, stdin, '\0') == EOF)
-   return NULL;
-   next = arg-buf + arg-len;
+   if (**next)
+   die(expected NUL but got: %s, *next);
+   (*next)++;
+   if (*next == input-buf + input-len)
+   return -1;
+   strbuf_addstr(arg, *next);
+   *next += arg-len;
}
-   return next;
+   return 0;
 }
 
-static void parse_cmd_update(const char *next)
+
+/*
+ * The following five parse_cmd_*() functions parse the corresponding
+ * command.  In each case, next points at the character following the
+ * command name and the following space.  They each return a pointer
+ * to the character terminating the command, and die with an
+ * explanatory message if there are any parsing problems.  All of
+ * these functions handle either text or binary format input,
+ * depending on how line_termination is set.
+ */
+
+static const char *parse_cmd_update(struct strbuf *input, const char *next)
 {
struct strbuf ref = STRBUF_INIT;
struct strbuf newvalue = STRBUF_INIT;
@@ -131,26 +157,28 @@ static void parse_cmd_update(const char *next)
 
update = update_alloc();
 
-   if ((next = parse_first_arg(next, ref)) != NULL  ref.buf[0])
+   parse_first_arg(input, next, ref);
+   if (ref.buf[0])
update_store_ref_name(update, ref.buf);
else
die(update line missing ref);
 
-   if ((next = parse_next_arg(next, newvalue)) != NULL)
+   if (!parse_next_arg(input, next, newvalue))
update_store_new_sha1(update, newvalue.buf);
else
die(update %s missing newvalue, ref.buf);
 
-   if ((next = parse_next_arg(next, oldvalue)) != NULL)
+   if (!parse_next_arg(input, next, oldvalue)) {

[PATCH 15/26] update-ref --stdin: Improve the error message for unexpected EOF

2014-03-10 Thread Michael Haggerty
Distinguish this error from the error that an argument is missing for
another reason.  Update the tests accordingly.

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 builtin/update-ref.c  |  4 ++--
 t/t1400-update-ref.sh | 10 +-
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/builtin/update-ref.c b/builtin/update-ref.c
index 5937291..0a81a11 100644
--- a/builtin/update-ref.c
+++ b/builtin/update-ref.c
@@ -156,8 +156,8 @@ static int parse_next_sha1(struct strbuf *input, const char 
**next,
 
  eof:
die(old ?
-   %s %s missing oldvalue :
-   %s %s missing newvalue,
+   %s %s: unexpected end of input when reading oldvalue :
+   %s %s: unexpected end of input when reading newvalue,
command, refname);
 }
 
diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh
index 7332753..e9a0103 100755
--- a/t/t1400-update-ref.sh
+++ b/t/t1400-update-ref.sh
@@ -709,7 +709,7 @@ test_expect_success 'stdin -z fails create with bad ref 
name' '
 test_expect_success 'stdin -z fails create with no new value' '
printf $F create $a stdin 
test_must_fail git update-ref -z --stdin stdin 2err 
-   grep fatal: create $a missing newvalue err
+   grep fatal: create $a: unexpected end of input when reading 
newvalue err
 '
 
 test_expect_success 'stdin -z fails create with too many arguments' '
@@ -733,13 +733,13 @@ test_expect_success 'stdin -z fails update with bad ref 
name' '
 test_expect_success 'stdin -z fails update with no new value' '
printf $F update $a stdin 
test_must_fail git update-ref -z --stdin stdin 2err 
-   grep fatal: update $a missing newvalue err
+   grep fatal: update $a: unexpected end of input when reading 
newvalue err
 '
 
 test_expect_success 'stdin -z fails update with no old value' '
printf $F update $a $m stdin 
test_must_fail git update-ref -z --stdin stdin 2err 
-   grep fatal: update $a missing oldvalue err
+   grep fatal: update $a: unexpected end of input when reading 
oldvalue err
 '
 
 test_expect_success 'stdin -z fails update with too many arguments' '
@@ -763,7 +763,7 @@ test_expect_success 'stdin -z fails delete with bad ref 
name' '
 test_expect_success 'stdin -z fails delete with no old value' '
printf $F delete $a stdin 
test_must_fail git update-ref -z --stdin stdin 2err 
-   grep fatal: delete $a missing oldvalue err
+   grep fatal: delete $a: unexpected end of input when reading 
oldvalue err
 '
 
 test_expect_success 'stdin -z fails delete with too many arguments' '
@@ -781,7 +781,7 @@ test_expect_success 'stdin -z fails verify with too many 
arguments' '
 test_expect_success 'stdin -z fails verify with no old value' '
printf $F verify $a stdin 
test_must_fail git update-ref -z --stdin stdin 2err 
-   grep fatal: verify $a missing oldvalue err
+   grep fatal: verify $a: unexpected end of input when reading 
oldvalue err
 '
 
 test_expect_success 'stdin -z fails option with unknown name' '
-- 
1.9.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


[PATCH 13/26] update-ref --stdin: Simplify error messages for missing oldvalues

2014-03-10 Thread Michael Haggerty
Instead of, for example,

fatal: update refs/heads/master missing [oldvalue] NUL

emit

fatal: update refs/heads/master missing oldvalue

Update the tests accordingly.

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 builtin/update-ref.c  | 6 +++---
 t/t1400-update-ref.sh | 6 +++---
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/builtin/update-ref.c b/builtin/update-ref.c
index e4c0854..a9eb5fe 100644
--- a/builtin/update-ref.c
+++ b/builtin/update-ref.c
@@ -176,7 +176,7 @@ static const char *parse_cmd_update(struct strbuf *input, 
const char *next)
if (*next != line_termination)
die(update %s has extra input: %s, update-ref_name, 
next);
} else if (!line_termination)
-   die(update %s missing [oldvalue] NUL, update-ref_name);
+   die(update %s missing oldvalue, update-ref_name);
 
return next;
 }
@@ -222,7 +222,7 @@ static const char *parse_cmd_delete(struct strbuf *input, 
const char *next)
if (update-have_old  is_null_sha1(update-old_sha1))
die(delete %s given zero oldvalue, 
update-ref_name);
} else if (!line_termination)
-   die(delete %s missing [oldvalue] NUL, update-ref_name);
+   die(delete %s missing oldvalue, update-ref_name);
 
if (*next != line_termination)
die(delete %s has extra input: %s, update-ref_name, next);
@@ -245,7 +245,7 @@ static const char *parse_cmd_verify(struct strbuf *input, 
const char *next)
update_store_old_sha1(verify, update, value.buf);
hashcpy(update-new_sha1, update-old_sha1);
} else if (!line_termination)
-   die(verify %s missing [oldvalue] NUL, update-ref_name);
+   die(verify %s missing oldvalue, update-ref_name);
 
if (*next != line_termination)
die(verify %s has extra input: %s, update-ref_name, next);
diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh
index 3045ae7..42fec4e 100755
--- a/t/t1400-update-ref.sh
+++ b/t/t1400-update-ref.sh
@@ -739,7 +739,7 @@ test_expect_success 'stdin -z fails update with no new 
value' '
 test_expect_success 'stdin -z fails update with no old value' '
printf $F update $a $m stdin 
test_must_fail git update-ref -z --stdin stdin 2err 
-   grep fatal: update $a missing \\[oldvalue\\] NUL err
+   grep fatal: update $a missing oldvalue err
 '
 
 test_expect_success 'stdin -z fails update with too many arguments' '
@@ -763,7 +763,7 @@ test_expect_success 'stdin -z fails delete with bad ref 
name' '
 test_expect_success 'stdin -z fails delete with no old value' '
printf $F delete $a stdin 
test_must_fail git update-ref -z --stdin stdin 2err 
-   grep fatal: delete $a missing \\[oldvalue\\] NUL err
+   grep fatal: delete $a missing oldvalue err
 '
 
 test_expect_success 'stdin -z fails delete with too many arguments' '
@@ -781,7 +781,7 @@ test_expect_success 'stdin -z fails verify with too many 
arguments' '
 test_expect_success 'stdin -z fails verify with no old value' '
printf $F verify $a stdin 
test_must_fail git update-ref -z --stdin stdin 2err 
-   grep fatal: verify $a missing \\[oldvalue\\] NUL err
+   grep fatal: verify $a missing oldvalue err
 '
 
 test_expect_success 'stdin -z fails option with unknown name' '
-- 
1.9.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


[PATCH 02/26] t1400: Provide sensible input to the command

2014-03-10 Thread Michael Haggerty
The old version was passing (among other things)

update SP refs/heads/c NUL NUL 0{40} NUL

to git update-ref -z --stdin to test whether the old-value check for
c is working.  But the newvalue is empty, which is not allowed for
the update command.

So, to be sure that we are testing what we want to test, provide a
legitimate newvalue on the update line.

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 t/t1400-update-ref.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh
index fa927d2..29391c6 100755
--- a/t/t1400-update-ref.sh
+++ b/t/t1400-update-ref.sh
@@ -912,7 +912,7 @@ test_expect_success 'stdin -z update refs works with 
identity updates' '
 
 test_expect_success 'stdin -z update refs fails with wrong old value' '
git update-ref $c $m 
-   printf $F update $a $m $m update $b $m $m update $c  
$Z stdin 
+   printf $F update $a $m $m update $b $m $m update $c $m 
$Z stdin 
test_must_fail git update-ref -z --stdin stdin 2err 
grep fatal: Cannot lock the ref '''$c''' err 
git rev-parse $m expect 
-- 
1.9.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


[PATCH 12/26] update-ref --stdin: Make error messages more consistent

2014-03-10 Thread Michael Haggerty
The old error messages emitted for invalid input sometimes said
oldvalue/newvalue and sometimes said old value/new value.
Convert them all to the former.  Update the tests accordingly.

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 builtin/update-ref.c  |  8 
 t/t1400-update-ref.sh | 14 +++---
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/builtin/update-ref.c b/builtin/update-ref.c
index 13a884a..e4c0854 100644
--- a/builtin/update-ref.c
+++ b/builtin/update-ref.c
@@ -40,7 +40,7 @@ static void update_store_new_sha1(const char *command,
  const char *newvalue)
 {
if (*newvalue  get_sha1(newvalue, update-new_sha1))
-   die(%s %s: invalid new value: %s,
+   die(%s %s: invalid newvalue: %s,
command, update-ref_name, newvalue);
 }
 
@@ -49,7 +49,7 @@ static void update_store_old_sha1(const char *command,
  const char *oldvalue)
 {
if (*oldvalue  get_sha1(oldvalue, update-old_sha1))
-   die(%s %s: invalid old value: %s,
+   die(%s %s: invalid oldvalue: %s,
command, update-ref_name, oldvalue);
 
/* We have an old value if non-empty, or if empty without -z */
@@ -198,7 +198,7 @@ static const char *parse_cmd_create(struct strbuf *input, 
const char *next)
die(create %s missing newvalue, update-ref_name);
 
if (is_null_sha1(update-new_sha1))
-   die(create %s given zero new value, update-ref_name);
+   die(create %s given zero newvalue, update-ref_name);
 
if (*next != line_termination)
die(create %s has extra input: %s, update-ref_name, next);
@@ -220,7 +220,7 @@ static const char *parse_cmd_delete(struct strbuf *input, 
const char *next)
if (!parse_next_arg(input, next, oldvalue)) {
update_store_old_sha1(delete, update, oldvalue.buf);
if (update-have_old  is_null_sha1(update-old_sha1))
-   die(delete %s given zero old value, update-ref_name);
+   die(delete %s given zero oldvalue, 
update-ref_name);
} else if (!line_termination)
die(delete %s missing [oldvalue] NUL, update-ref_name);
 
diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh
index c5be870..3045ae7 100755
--- a/t/t1400-update-ref.sh
+++ b/t/t1400-update-ref.sh
@@ -518,21 +518,21 @@ test_expect_success 'stdin update ref fails with wrong 
old value' '
 test_expect_success 'stdin update ref fails with bad old value' '
echo update $c $m does-not-exist stdin 
test_must_fail git update-ref --stdin stdin 2err 
-   grep fatal: update $c: invalid old value: does-not-exist err 
+   grep fatal: update $c: invalid oldvalue: does-not-exist err 
test_must_fail git rev-parse --verify -q $c
 '
 
 test_expect_success 'stdin create ref fails with bad new value' '
echo create $c does-not-exist stdin 
test_must_fail git update-ref --stdin stdin 2err 
-   grep fatal: create $c: invalid new value: does-not-exist err 
+   grep fatal: create $c: invalid newvalue: does-not-exist err 
test_must_fail git rev-parse --verify -q $c
 '
 
 test_expect_success 'stdin create ref fails with zero new value' '
echo create $c  stdin 
test_must_fail git update-ref --stdin stdin 2err 
-   grep fatal: create $c given zero new value err 
+   grep fatal: create $c given zero newvalue err 
test_must_fail git rev-parse --verify -q $c
 '
 
@@ -556,7 +556,7 @@ test_expect_success 'stdin delete ref fails with wrong old 
value' '
 test_expect_success 'stdin delete ref fails with zero old value' '
echo delete $a  stdin 
test_must_fail git update-ref --stdin stdin 2err 
-   grep fatal: delete $a given zero old value err 
+   grep fatal: delete $a given zero oldvalue err 
git rev-parse $m expect 
git rev-parse $a actual 
test_cmp expect actual
@@ -840,14 +840,14 @@ test_expect_success 'stdin -z update ref fails with wrong 
old value' '
 test_expect_success 'stdin -z update ref fails with bad old value' '
printf $F update $c $m does-not-exist stdin 
test_must_fail git update-ref -z --stdin stdin 2err 
-   grep fatal: update $c: invalid old value: does-not-exist err 
+   grep fatal: update $c: invalid oldvalue: does-not-exist err 
test_must_fail git rev-parse --verify -q $c
 '
 
 test_expect_success 'stdin -z create ref fails with bad new value' '
printf $F create $c does-not-exist stdin 
test_must_fail git update-ref -z --stdin stdin 2err 
-   grep fatal: create $c: invalid new value: does-not-exist err 
+   grep fatal: create $c: invalid newvalue: does-not-exist err 
test_must_fail git rev-parse --verify -q $c
 '
 
@@ -878,7 +878,7 @@ test_expect_success 'stdin -z delete ref fails with wrong 
old 

[PATCH 17/26] refs: Add a concept of a reference transaction

2014-03-10 Thread Michael Haggerty
Build out the API for dealing with a bunch of reference checks and
changes within a transaction.  Define an opaque ref_transaction type
that is managed entirely within refs.c.  Introduce functions for
starting a transaction, adding updates to a transaction, and
committing a transaction.

This API will soon replace update_refs().

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 refs.c | 85 ++
 refs.h | 63 +
 2 files changed, 148 insertions(+)

diff --git a/refs.c b/refs.c
index 0963077..54260ce 100644
--- a/refs.c
+++ b/refs.c
@@ -3267,6 +3267,85 @@ static int update_ref_write(const char *action, const 
char *refname,
return 0;
 }
 
+/*
+ * Data structure for holding a reference transaction, which can
+ * consist of checks and updates to multiple references, carried out
+ * as atomically as possible.  This structure is opaque to callers.
+ */
+struct ref_transaction {
+   struct ref_update **updates;
+   size_t alloc;
+   size_t nr;
+};
+
+struct ref_transaction *create_ref_transaction(void)
+{
+   return xcalloc(1, sizeof(struct ref_transaction));
+}
+
+void free_ref_transaction(struct ref_transaction *transaction)
+{
+   int i;
+
+   for (i = 0; i  transaction-nr; i++) {
+   struct ref_update *update = transaction-updates[i];
+
+   free((char *)update-ref_name);
+   free(update);
+   }
+
+   free(transaction-updates);
+   free(transaction);
+}
+
+static struct ref_update *add_update(struct ref_transaction *transaction,
+const char *refname)
+{
+   struct ref_update *update = xcalloc(1, sizeof(*update));
+
+   update-ref_name = xstrdup(refname);
+   ALLOC_GROW(transaction-updates, transaction-nr + 1, 
transaction-alloc);
+   transaction-updates[transaction-nr++] = update;
+   return update;
+}
+
+void queue_update_ref(struct ref_transaction *transaction, const char *refname,
+ unsigned char *new_sha1, unsigned char *old_sha1,
+ int flags, int have_old)
+{
+   struct ref_update *update = add_update(transaction, refname);
+
+   hashcpy(update-new_sha1, new_sha1);
+   update-flags = flags;
+   update-have_old = have_old;
+   if (have_old)
+   hashcpy(update-old_sha1, old_sha1);
+}
+
+void queue_create_ref(struct ref_transaction *transaction, const char *refname,
+ unsigned char *new_sha1,
+ int flags)
+{
+   struct ref_update *update = add_update(transaction, refname);
+
+   hashcpy(update-new_sha1, new_sha1);
+   hashclr(update-old_sha1);
+   update-flags = flags;
+   update-have_old = 1;
+}
+
+void queue_delete_ref(struct ref_transaction *transaction, const char *refname,
+ unsigned char *old_sha1,
+ int flags, int have_old)
+{
+   struct ref_update *update = add_update(transaction, refname);
+
+   update-flags = flags;
+   update-have_old = have_old;
+   if (have_old)
+   hashcpy(update-old_sha1, old_sha1);
+}
+
 int update_ref(const char *action, const char *refname,
   const unsigned char *sha1, const unsigned char *oldval,
   int flags, enum action_on_err onerr)
@@ -3378,6 +3457,12 @@ cleanup:
return ret;
 }
 
+int commit_ref_transaction(struct ref_transaction *transaction,
+  const char *msg, enum action_on_err onerr)
+{
+   return update_refs(msg, transaction-updates, transaction-nr, onerr);
+}
+
 char *shorten_unambiguous_ref(const char *refname, int strict)
 {
int i;
diff --git a/refs.h b/refs.h
index 08e60ac..2848fb7 100644
--- a/refs.h
+++ b/refs.h
@@ -24,6 +24,8 @@ struct ref_update {
int have_old; /* 1 if old_sha1 is valid, 0 otherwise */
 };
 
+struct ref_transaction;
+
 /*
  * Bit values set in the flags argument passed to each_ref_fn():
  */
@@ -220,6 +222,67 @@ enum action_on_err {
UPDATE_REFS_QUIET_ON_ERR
 };
 
+/*
+ * Allocate and initialize a ref_transaction object.  The object must
+ * be freed by calling free_ref_transaction().
+ */
+struct ref_transaction *create_ref_transaction(void);
+
+/*
+ * Free a ref_transaction and all associated data.  This function does
+ * not commit the transaction; that must be done first (if desired) by
+ * calling commit_ref_transaction().
+ */
+void free_ref_transaction(struct ref_transaction *transaction);
+
+
+/*
+ * The following functions add a reference check or update to a
+ * ref_transaction.  In all of them, refname is the name of the
+ * reference to be affected.  The functions make internal copies of
+ * refname, so the caller retains ownership of the parameter.  flags
+ * can be REF_NODEREF; it is passed to update_ref_lock().
+ */
+
+
+/*
+ * Add a reference update to transaction.  new_sha1 is the value that
+ 

[PATCH 14/26] update-ref.c: Extract a new function, parse_next_sha1()

2014-03-10 Thread Michael Haggerty
Replace three functions, update_store_new_sha1(),
update_store_old_sha1(), and parse_next_arg(), with a single function,
parse_next_sha1().  The new function takes care of a whole argument,
including checking whether it is there, converting it to an SHA-1, and
emitting errors on EOF or for invalid values.  The return value
indicates whether the argument was present or absent, which requires
a bit of intelligence because absent values are represented
differently depending on whether -z was used.

The new interface means that the calling functions, parse_cmd_*(),
don't have to interpret the result differently based on the
line_termination mode that is in effect.  It also means that
parse_cmd_create() can distinguish unambiguously between an empty new
value and a zeros new value, which fixes a failure in t1400.

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 builtin/update-ref.c  | 138 +++---
 t/t1400-update-ref.sh |   2 +-
 2 files changed, 77 insertions(+), 63 deletions(-)

diff --git a/builtin/update-ref.c b/builtin/update-ref.c
index a9eb5fe..5937291 100644
--- a/builtin/update-ref.c
+++ b/builtin/update-ref.c
@@ -35,27 +35,6 @@ static struct ref_update *update_alloc(void)
return update;
 }
 
-static void update_store_new_sha1(const char *command,
- struct ref_update *update,
- const char *newvalue)
-{
-   if (*newvalue  get_sha1(newvalue, update-new_sha1))
-   die(%s %s: invalid newvalue: %s,
-   command, update-ref_name, newvalue);
-}
-
-static void update_store_old_sha1(const char *command,
- struct ref_update *update,
- const char *oldvalue)
-{
-   if (*oldvalue  get_sha1(oldvalue, update-old_sha1))
-   die(%s %s: invalid oldvalue: %s,
-   command, update-ref_name, oldvalue);
-
-   /* We have an old value if non-empty, or if empty without -z */
-   update-have_old = *oldvalue || line_termination;
-}
-
 /*
  * Parse one whitespace- or NUL-terminated, possibly C-quoted argument
  * and append the result to arg.  Return a pointer to the terminator.
@@ -112,35 +91,74 @@ static char *parse_refname(struct strbuf *input, const 
char **next)
 }
 
 /*
- * Parse a SP/NUL separator followed by the next SP- or NUL-terminated
- * argument, if any.  If there is an argument, write it to arg, set
- * *next to point at the character terminating the argument, and
+ * Parse an argument separator followed by the next argument, if any.
+ * If there is an argument, convert it to a SHA-1, write it to sha1,
+ * set *next to point at the character terminating the argument, and
  * return 0.  If there is no argument at all (not even the empty
- * string), return a non-zero result and leave *next unchanged.
+ * string), return 1 and leave *next unchanged.  If the value is
+ * provided but cannot be converted to a SHA-1, die.
  */
-static int parse_next_arg(struct strbuf *input, const char **next,
- struct strbuf *arg)
+static int parse_next_sha1(struct strbuf *input, const char **next,
+  unsigned char *sha1,
+  const char *command, const char *refname, int old)
 {
-   strbuf_reset(arg);
+   struct strbuf arg = STRBUF_INIT;
+   int ret = 0;
+
+   if (*next == input-buf + input-len)
+   goto eof;
+
if (line_termination) {
/* Without -z, consume SP and use next argument */
if (!**next || **next == line_termination)
-   return -1;
+   return 1;
if (**next != ' ')
-   die(expected SP but got: %s, *next);
+   die(%s %s: expected SP but got: %s,
+   command, refname, *next);
(*next)++;
-   *next = parse_arg(*next, arg);
+   *next = parse_arg(*next, arg);
+   if (arg.len) {
+   if (get_sha1(arg.buf, sha1))
+   goto invalid;
+   } else {
+   /* Without -z, an empty value means all zeros: */
+   hashclr(sha1);
+   }
} else {
/* With -z, read the next NUL-terminated line */
if (**next)
-   die(expected NUL but got: %s, *next);
+   die(%s %s: expected NUL but got: %s,
+   command, refname, *next);
(*next)++;
if (*next == input-buf + input-len)
-   return -1;
-   strbuf_addstr(arg, *next);
-   *next += arg-len;
+   goto eof;
+   strbuf_addstr(arg, *next);
+   *next += arg.len;
+
+   if (arg.len) {
+   if 

[PATCH 22/26] commit_ref_transaction(): Introduce temporary variables

2014-03-10 Thread Michael Haggerty
Use temporary variables in the for-loop blocks to simplify expressions
in the rest of the loop.

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 refs.c | 25 -
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/refs.c b/refs.c
index 335d0e2..ec638e9 100644
--- a/refs.c
+++ b/refs.c
@@ -3424,10 +3424,12 @@ int commit_ref_transaction(struct ref_transaction 
*transaction,
 
/* Acquire all locks while verifying old values */
for (i = 0; i  n; i++) {
-   locks[i] = update_ref_lock(updates[i]-refname,
-  (updates[i]-have_old ?
-   updates[i]-old_sha1 : NULL),
-  updates[i]-flags,
+   struct ref_update *update = updates[i];
+
+   locks[i] = update_ref_lock(update-refname,
+  (update-have_old ?
+   update-old_sha1 : NULL),
+  update-flags,
   types[i], onerr);
if (!locks[i]) {
ret = 1;
@@ -3436,23 +3438,28 @@ int commit_ref_transaction(struct ref_transaction 
*transaction,
}
 
/* Perform updates first so live commits remain referenced */
-   for (i = 0; i  n; i++)
-   if (!is_null_sha1(updates[i]-new_sha1)) {
+   for (i = 0; i  n; i++) {
+   struct ref_update *update = updates[i];
+
+   if (!is_null_sha1(update-new_sha1)) {
ret = update_ref_write(msg,
-  updates[i]-refname,
-  updates[i]-new_sha1,
+  update-refname,
+  update-new_sha1,
   locks[i], onerr);
locks[i] = NULL; /* freed by update_ref_write */
if (ret)
goto cleanup;
}
+   }
 
/* Perform deletes now that updates are safely completed */
-   for (i = 0; i  n; i++)
+   for (i = 0; i  n; i++) {
if (locks[i]) {
delnames[delnum++] = locks[i]-ref_name;
ret |= delete_ref_loose(locks[i], types[i]);
}
+   }
+
ret |= repack_without_refs(delnames, delnum);
for (i = 0; i  delnum; i++)
unlink_or_warn(git_path(logs/%s, delnames[i]));
-- 
1.9.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


[PATCH 26/26] commit_ref_transaction(): Work with transaction-updates in place

2014-03-10 Thread Michael Haggerty
Now that we free the transaction when we are done, there is no need to
make a copy of transaction-updates before working with it.

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 refs.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/refs.c b/refs.c
index d83fc7b..ea33adc 100644
--- a/refs.c
+++ b/refs.c
@@ -3402,19 +3402,17 @@ int commit_ref_transaction(struct ref_transaction 
*transaction,
   const char *msg, enum action_on_err onerr)
 {
int ret = 0, delnum = 0, i;
-   struct ref_update **updates;
const char **delnames;
int n = transaction-nr;
+   struct ref_update **updates = transaction-updates;
 
if (!n)
return 0;
 
/* Allocate work space */
-   updates = xmalloc(sizeof(*updates) * n);
delnames = xmalloc(sizeof(*delnames) * n);
 
/* Copy, sort, and reject duplicate refs */
-   memcpy(updates, transaction-updates, sizeof(*updates) * n);
qsort(updates, n, sizeof(*updates), ref_update_compare);
ret = ref_update_reject_duplicates(updates, n, onerr);
if (ret)
@@ -3469,7 +3467,6 @@ cleanup:
for (i = 0; i  n; i++)
if (updates[i]-lock)
unlock_ref(updates[i]-lock);
-   free(updates);
free(delnames);
free_ref_transaction(transaction);
return ret;
-- 
1.9.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


[PATCH 05/26] t1400: Add some more tests involving quoted arguments

2014-03-10 Thread Michael Haggerty
Previously there were no good tests of C-quoted arguments.

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 t/t1400-update-ref.sh | 26 +-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh
index 5836842..627aaaf 100755
--- a/t/t1400-update-ref.sh
+++ b/t/t1400-update-ref.sh
@@ -350,12 +350,18 @@ test_expect_success 'stdin fails on unknown command' '
grep fatal: unknown command: unknown $a err
 '
 
-test_expect_success 'stdin fails on badly quoted input' '
+test_expect_success 'stdin fails on unbalanced quotes' '
echo create $a \master stdin 
test_must_fail git update-ref --stdin stdin 2err 
grep fatal: badly quoted argument: \\\master err
 '
 
+test_expect_success 'stdin fails on invalid escape' '
+   echo create $a \ma\zter\ stdin 
+   test_must_fail git update-ref --stdin stdin 2err 
+   grep fatal: badly quoted argument: \\\mazter\\\ err
+'
+
 test_expect_success 'stdin fails on junk after quoted argument' '
echo create \$a\master stdin 
test_must_fail git update-ref --stdin stdin 2err 
@@ -458,6 +464,24 @@ test_expect_success 'stdin create ref works' '
test_cmp expect actual
 '
 
+test_expect_success 'stdin succeeds with quoted argument' '
+   git update-ref -d $a 
+   echo create $a \$m\ stdin 
+   git update-ref --stdin stdin 
+   git rev-parse $m expect 
+   git rev-parse $a actual 
+   test_cmp expect actual
+'
+
+test_expect_success 'stdin succeeds with escaped character' '
+   git update-ref -d $a 
+   echo create $a \ma\\163ter\ stdin 
+   git update-ref --stdin stdin 
+   git rev-parse $m expect 
+   git rev-parse $a actual 
+   test_cmp expect actual
+'
+
 test_expect_success 'stdin update ref creates with zero old value' '
echo update $b $m $Z stdin 
git update-ref --stdin stdin 
-- 
1.9.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


[PATCH 10/26] update-ref.c: Extract a new function, parse_refname()

2014-03-10 Thread Michael Haggerty
There is no reason to obscure the fact that parse_first_arg() always
parses refnames.  Form the new function by combining parse_first_arg()
and update_store_ref_name().

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 builtin/update-ref.c | 90 
 1 file changed, 41 insertions(+), 49 deletions(-)

diff --git a/builtin/update-ref.c b/builtin/update-ref.c
index 51adf2d..0dc2061 100644
--- a/builtin/update-ref.c
+++ b/builtin/update-ref.c
@@ -35,14 +35,6 @@ static struct ref_update *update_alloc(void)
return update;
 }
 
-static void update_store_ref_name(struct ref_update *update,
- const char *ref_name)
-{
-   if (check_refname_format(ref_name, REFNAME_ALLOW_ONELEVEL))
-   die(invalid ref format: %s, ref_name);
-   update-ref_name = xstrdup(ref_name);
-}
-
 static void update_store_new_sha1(struct ref_update *update,
  const char *newvalue)
 {
@@ -86,23 +78,35 @@ static const char *parse_arg(const char *next, struct 
strbuf *arg)
 }
 
 /*
- * Parse the argument immediately after command SP.  If not -z, then
- * handle C-quoting.  Write the argument to arg.  Set *next to point
- * at the character that terminates the argument.  Die if C-quoting is
- * malformed.
+ * Parse the reference name immediately after command SP.  If not
+ * -z, then handle C-quoting.  Return a pointer to a newly allocated
+ * string containing the name of the reference, or NULL if there was
+ * an error.  Update *next to point at the character that terminates
+ * the argument.  Die if C-quoting is malformed or the reference name
+ * is invalid.
  */
-static void parse_first_arg(struct strbuf *input, const char **next,
-   struct strbuf *arg)
+static char *parse_refname(struct strbuf *input, const char **next)
 {
-   strbuf_reset(arg);
+   struct strbuf ref = STRBUF_INIT;
+
if (line_termination) {
/* Without -z, use the next argument */
-   *next = parse_arg(*next, arg);
+   *next = parse_arg(*next, ref);
} else {
/* With -z, use everything up to the next NUL */
-   strbuf_addstr(arg, *next);
-   *next += arg-len;
+   strbuf_addstr(ref, *next);
+   *next += ref.len;
+   }
+
+   if (!ref.len) {
+   strbuf_release(ref);
+   return NULL;
}
+
+   if (check_refname_format(ref.buf, REFNAME_ALLOW_ONELEVEL))
+   die(invalid ref format: %s, ref.buf);
+
+   return strbuf_detach(ref, NULL);
 }
 
 /*
@@ -150,111 +154,99 @@ static int parse_next_arg(struct strbuf *input, const 
char **next,
 
 static const char *parse_cmd_update(struct strbuf *input, const char *next)
 {
-   struct strbuf ref = STRBUF_INIT;
struct strbuf newvalue = STRBUF_INIT;
struct strbuf oldvalue = STRBUF_INIT;
struct ref_update *update;
 
update = update_alloc();
 
-   parse_first_arg(input, next, ref);
-   if (ref.buf[0])
-   update_store_ref_name(update, ref.buf);
-   else
+   update-ref_name = parse_refname(input, next);
+   if (!update-ref_name)
die(update line missing ref);
 
if (!parse_next_arg(input, next, newvalue))
update_store_new_sha1(update, newvalue.buf);
else
-   die(update %s missing newvalue, ref.buf);
+   die(update %s missing newvalue, update-ref_name);
 
if (!parse_next_arg(input, next, oldvalue)) {
update_store_old_sha1(update, oldvalue.buf);
if (*next != line_termination)
-   die(update %s has extra input: %s, ref.buf, next);
+   die(update %s has extra input: %s, update-ref_name, 
next);
} else if (!line_termination)
-   die(update %s missing [oldvalue] NUL, ref.buf);
+   die(update %s missing [oldvalue] NUL, update-ref_name);
 
return next;
 }
 
 static const char *parse_cmd_create(struct strbuf *input, const char *next)
 {
-   struct strbuf ref = STRBUF_INIT;
struct strbuf newvalue = STRBUF_INIT;
struct ref_update *update;
 
update = update_alloc();
 
-   parse_first_arg(input, next, ref);
-   if (ref.buf[0])
-   update_store_ref_name(update, ref.buf);
-   else
+   update-ref_name = parse_refname(input, next);
+   if (!update-ref_name)
die(create line missing ref);
 
if (!parse_next_arg(input, next, newvalue))
update_store_new_sha1(update, newvalue.buf);
else
-   die(create %s missing newvalue, ref.buf);
+   die(create %s missing newvalue, update-ref_name);
 
if (is_null_sha1(update-new_sha1))
-   die(create %s given zero new value, ref.buf);
+   die(create %s given zero new 

[PATCH 07/26] update_refs(): Fix constness

2014-03-10 Thread Michael Haggerty
Since full const correctness is beyond the ability of C's type system,
just put the const where it doesn't do any harm.  A (struct ref_update
**) can be passed to a (struct ref_update * const *) argument, but not
to a (const struct ref_update **) argument.

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 builtin/update-ref.c | 2 +-
 refs.c   | 2 +-
 refs.h   | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/builtin/update-ref.c b/builtin/update-ref.c
index f6345e5..a8a68e8 100644
--- a/builtin/update-ref.c
+++ b/builtin/update-ref.c
@@ -14,7 +14,7 @@ static const char * const git_update_ref_usage[] = {
 
 static int updates_alloc;
 static int updates_count;
-static const struct ref_update **updates;
+static struct ref_update **updates;
 
 static char line_termination = '\n';
 static int update_flags;
diff --git a/refs.c b/refs.c
index 58faf95..0963077 100644
--- a/refs.c
+++ b/refs.c
@@ -3306,7 +3306,7 @@ static int ref_update_reject_duplicates(struct ref_update 
**updates, int n,
return 0;
 }
 
-int update_refs(const char *action, const struct ref_update **updates_orig,
+int update_refs(const char *action, struct ref_update * const *updates_orig,
int n, enum action_on_err onerr)
 {
int ret = 0, delnum = 0, i;
diff --git a/refs.h b/refs.h
index a713b34..08e60ac 100644
--- a/refs.h
+++ b/refs.h
@@ -228,7 +228,7 @@ int update_ref(const char *action, const char *refname,
 /**
  * Lock all refs and then perform all modifications.
  */
-int update_refs(const char *action, const struct ref_update **updates,
+int update_refs(const char *action, struct ref_update * const *updates,
int n, enum action_on_err onerr);
 
 extern int parse_hide_refs_config(const char *var, const char *value, const 
char *);
-- 
1.9.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


[PATCH 20/26] struct ref_update: Rename field ref_name to refname

2014-03-10 Thread Michael Haggerty
This is consistent with the usual nomenclature.

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 refs.c | 18 +-
 refs.h |  2 +-
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/refs.c b/refs.c
index 91af0a0..5d08cdf 100644
--- a/refs.c
+++ b/refs.c
@@ -3274,7 +3274,7 @@ static int update_ref_write(const char *action, const 
char *refname,
  * value or to zero to ensure the ref does not exist before update.
  */
 struct ref_update {
-   const char *ref_name;
+   const char *refname;
unsigned char new_sha1[20];
unsigned char old_sha1[20];
int flags; /* REF_NODEREF? */
@@ -3304,7 +3304,7 @@ void free_ref_transaction(struct ref_transaction 
*transaction)
for (i = 0; i  transaction-nr; i++) {
struct ref_update *update = transaction-updates[i];
 
-   free((char *)update-ref_name);
+   free((char *)update-refname);
free(update);
}
 
@@ -3317,7 +3317,7 @@ static struct ref_update *add_update(struct 
ref_transaction *transaction,
 {
struct ref_update *update = xcalloc(1, sizeof(*update));
 
-   update-ref_name = xstrdup(refname);
+   update-refname = xstrdup(refname);
ALLOC_GROW(transaction-updates, transaction-nr + 1, 
transaction-alloc);
transaction-updates[transaction-nr++] = update;
return update;
@@ -3375,7 +3375,7 @@ static int ref_update_compare(const void *r1, const void 
*r2)
 {
const struct ref_update * const *u1 = r1;
const struct ref_update * const *u2 = r2;
-   return strcmp((*u1)-ref_name, (*u2)-ref_name);
+   return strcmp((*u1)-refname, (*u2)-refname);
 }
 
 static int ref_update_reject_duplicates(struct ref_update **updates, int n,
@@ -3383,14 +3383,14 @@ static int ref_update_reject_duplicates(struct 
ref_update **updates, int n,
 {
int i;
for (i = 1; i  n; i++)
-   if (!strcmp(updates[i - 1]-ref_name, updates[i]-ref_name)) {
+   if (!strcmp(updates[i - 1]-refname, updates[i]-refname)) {
const char *str =
Multiple updates for ref '%s' not allowed.;
switch (onerr) {
case UPDATE_REFS_MSG_ON_ERR:
-   error(str, updates[i]-ref_name); break;
+   error(str, updates[i]-refname); break;
case UPDATE_REFS_DIE_ON_ERR:
-   die(str, updates[i]-ref_name); break;
+   die(str, updates[i]-refname); break;
case UPDATE_REFS_QUIET_ON_ERR:
break;
}
@@ -3427,7 +3427,7 @@ int commit_ref_transaction(struct ref_transaction 
*transaction,
 
/* Acquire all locks while verifying old values */
for (i = 0; i  n; i++) {
-   locks[i] = update_ref_lock(updates[i]-ref_name,
+   locks[i] = update_ref_lock(updates[i]-refname,
   (updates[i]-have_old ?
updates[i]-old_sha1 : NULL),
   updates[i]-flags,
@@ -3442,7 +3442,7 @@ int commit_ref_transaction(struct ref_transaction 
*transaction,
for (i = 0; i  n; i++)
if (!is_null_sha1(updates[i]-new_sha1)) {
ret = update_ref_write(msg,
-  updates[i]-ref_name,
+  updates[i]-refname,
   updates[i]-new_sha1,
   locks[i], onerr);
locks[i] = NULL; /* freed by update_ref_write */
diff --git a/refs.h b/refs.h
index b1f8b74..cc24213 100644
--- a/refs.h
+++ b/refs.h
@@ -154,7 +154,7 @@ extern void unlock_ref(struct ref_lock *lock);
 extern int write_ref_sha1(struct ref_lock *lock, const unsigned char *sha1, 
const char *msg);
 
 /** Setup reflog before using. **/
-int log_ref_setup(const char *ref_name, char *logfile, int bufsize);
+int log_ref_setup(const char *refname, char *logfile, int bufsize);
 
 /** Reads log for the value of ref during at_time. **/
 extern int read_ref_at(const char *refname, unsigned long at_time, int cnt,
-- 
1.9.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


[PATCH 09/26] parse_cmd_verify(): Copy old_sha1 instead of evaluating oldvalue twice

2014-03-10 Thread Michael Haggerty
Aside from avoiding work, this makes it transparently obvious that
old_sha1 and new_sha1 are identical.

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 builtin/update-ref.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/builtin/update-ref.c b/builtin/update-ref.c
index 5f197fe..51adf2d 100644
--- a/builtin/update-ref.c
+++ b/builtin/update-ref.c
@@ -249,7 +249,7 @@ static const char *parse_cmd_verify(struct strbuf *input, 
const char *next)
 
if (!parse_next_arg(input, next, value)) {
update_store_old_sha1(update, value.buf);
-   update_store_new_sha1(update, value.buf);
+   hashcpy(update-new_sha1, update-old_sha1);
} else if (!line_termination)
die(verify %s missing [oldvalue] NUL, ref.buf);
 
-- 
1.9.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


[PATCH 16/26] update-ref --stdin: Harmonize error messages

2014-03-10 Thread Michael Haggerty
Make (most of) the error messages for invalid input have the same
format [1]:

$COMMAND [SP $REFNAME]: $MESSAGE

Update the tests accordingly.

[1] A few error messages still have their old form, because $COMMAND
and $REFNAME aren't passed all the way down the call stack.

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
Making more error messages conform to the new pattern is an exercise
left to the reader (or maybe the writer if I find time to get back to
it).

 builtin/update-ref.c  | 24 
 t/t1400-update-ref.sh | 32 
 2 files changed, 28 insertions(+), 28 deletions(-)

diff --git a/builtin/update-ref.c b/builtin/update-ref.c
index 0a81a11..ac41635 100644
--- a/builtin/update-ref.c
+++ b/builtin/update-ref.c
@@ -180,17 +180,17 @@ static const char *parse_cmd_update(struct strbuf *input, 
const char *next)
 
update-ref_name = parse_refname(input, next);
if (!update-ref_name)
-   die(update line missing ref);
+   die(update: missing ref);
 
if (parse_next_sha1(input, next, update-new_sha1,
update, update-ref_name, 0))
-   die(update %s missing newvalue, update-ref_name);
+   die(update %s: missing newvalue, update-ref_name);
 
update-have_old = !parse_next_sha1(input, next, update-old_sha1,
update, update-ref_name, 1);
 
if (*next != line_termination)
-   die(update %s has extra input: %s, update-ref_name, next);
+   die(update %s: extra input: %s, update-ref_name, next);
 
return next;
 }
@@ -203,17 +203,17 @@ static const char *parse_cmd_create(struct strbuf *input, 
const char *next)
 
update-ref_name = parse_refname(input, next);
if (!update-ref_name)
-   die(create line missing ref);
+   die(create: missing ref);
 
if (parse_next_sha1(input, next, update-new_sha1,
create, update-ref_name, 0))
-   die(create %s missing newvalue, update-ref_name);
+   die(create %s: missing newvalue, update-ref_name);
 
if (is_null_sha1(update-new_sha1))
-   die(create %s given zero newvalue, update-ref_name);
+   die(create %s: zero newvalue, update-ref_name);
 
if (*next != line_termination)
-   die(create %s has extra input: %s, update-ref_name, next);
+   die(create %s: extra input: %s, update-ref_name, next);
 
return next;
 }
@@ -226,19 +226,19 @@ static const char *parse_cmd_delete(struct strbuf *input, 
const char *next)
 
update-ref_name = parse_refname(input, next);
if (!update-ref_name)
-   die(delete line missing ref);
+   die(delete: missing ref);
 
if (parse_next_sha1(input, next, update-old_sha1,
delete, update-ref_name, 1)) {
update-have_old = 0;
} else {
if (is_null_sha1(update-old_sha1))
-   die(delete %s given zero oldvalue, 
update-ref_name);
+   die(delete %s: zero oldvalue, update-ref_name);
update-have_old = 1;
}
 
if (*next != line_termination)
-   die(delete %s has extra input: %s, update-ref_name, next);
+   die(delete %s: extra input: %s, update-ref_name, next);
 
return next;
 }
@@ -251,7 +251,7 @@ static const char *parse_cmd_verify(struct strbuf *input, 
const char *next)
 
update-ref_name = parse_refname(input, next);
if (!update-ref_name)
-   die(verify line missing ref);
+   die(verify: missing ref);
 
if (parse_next_sha1(input, next, update-old_sha1,
verify, update-ref_name, 1)) {
@@ -262,7 +262,7 @@ static const char *parse_cmd_verify(struct strbuf *input, 
const char *next)
}
 
if (*next != line_termination)
-   die(verify %s has extra input: %s, update-ref_name, next);
+   die(verify %s: extra input: %s, update-ref_name, next);
 
return next;
 }
diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh
index e9a0103..3cc5c66 100755
--- a/t/t1400-update-ref.sh
+++ b/t/t1400-update-ref.sh
@@ -371,7 +371,7 @@ test_expect_success 'stdin fails on junk after quoted 
argument' '
 test_expect_success 'stdin fails create with no ref' '
echo create  stdin 
test_must_fail git update-ref --stdin stdin 2err 
-   grep fatal: create line missing ref err
+   grep fatal: create: missing ref err
 '
 
 test_expect_success 'stdin fails create with bad ref name' '
@@ -383,19 +383,19 @@ test_expect_success 'stdin fails create with bad ref 
name' '
 test_expect_success 'stdin fails create with no new value' '
echo create $a stdin 
test_must_fail git update-ref --stdin stdin 2err 
-   grep fatal: 

[PATCH 25/26] commit_ref_transaction(): Also free the ref_transaction

2014-03-10 Thread Michael Haggerty
Change commit_ref_transaction() to also free the associated data, to
absolve the caller from having to do it.

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 builtin/update-ref.c |  1 -
 refs.c   |  1 +
 refs.h   | 11 ++-
 3 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/builtin/update-ref.c b/builtin/update-ref.c
index ffed061..b33288c 100644
--- a/builtin/update-ref.c
+++ b/builtin/update-ref.c
@@ -346,7 +346,6 @@ int cmd_update_ref(int argc, const char **argv, const char 
*prefix)
update_refs_stdin();
ret = commit_ref_transaction(transaction, msg,
 UPDATE_REFS_DIE_ON_ERR);
-   free_ref_transaction(transaction);
return ret;
}
 
diff --git a/refs.c b/refs.c
index 1fd38b0..d83fc7b 100644
--- a/refs.c
+++ b/refs.c
@@ -3471,6 +3471,7 @@ cleanup:
unlock_ref(updates[i]-lock);
free(updates);
free(delnames);
+   free_ref_transaction(transaction);
return ret;
 }
 
diff --git a/refs.h b/refs.h
index cc24213..754894b 100644
--- a/refs.h
+++ b/refs.h
@@ -210,14 +210,15 @@ enum action_on_err {
 
 /*
  * Allocate and initialize a ref_transaction object.  The object must
- * be freed by calling free_ref_transaction().
+ * be freed by calling commit_ref_transaction() or
+ * free_ref_transaction().
  */
 struct ref_transaction *create_ref_transaction(void);
 
 /*
- * Free a ref_transaction and all associated data.  This function does
- * not commit the transaction; that must be done first (if desired) by
- * calling commit_ref_transaction().
+ * Free a ref_transaction and all associated data.  This function
+ * should be called to free a ref_transaction that will not be
+ * committed.
  */
 void free_ref_transaction(struct ref_transaction *transaction);
 
@@ -264,7 +265,7 @@ void queue_delete_ref(struct ref_transaction *transaction, 
const char *refname,
 /*
  * Commit all of the changes that have been queued in transaction, as
  * atomically as possible.  Return a nonzero value if there is a
- * problem.  The transaction is unmodified by this function.
+ * problem.  The transaction is freed by this function.
  */
 int commit_ref_transaction(struct ref_transaction *transaction,
   const char *msg, enum action_on_err onerr);
-- 
1.9.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


[PATCH 24/26] struct ref_update: Add type field

2014-03-10 Thread Michael Haggerty
This is temporary space for commit_ref_transaction()

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 refs.c | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/refs.c b/refs.c
index 73aec88..1fd38b0 100644
--- a/refs.c
+++ b/refs.c
@@ -3279,6 +3279,7 @@ struct ref_update {
int flags; /* REF_NODEREF? */
int have_old; /* 1 if old_sha1 is valid, 0 otherwise */
struct ref_lock *lock;
+   int type;
const char refname[FLEX_ARRAY];
 };
 
@@ -3402,7 +3403,6 @@ int commit_ref_transaction(struct ref_transaction 
*transaction,
 {
int ret = 0, delnum = 0, i;
struct ref_update **updates;
-   int *types;
const char **delnames;
int n = transaction-nr;
 
@@ -3411,7 +3411,6 @@ int commit_ref_transaction(struct ref_transaction 
*transaction,
 
/* Allocate work space */
updates = xmalloc(sizeof(*updates) * n);
-   types = xmalloc(sizeof(*types) * n);
delnames = xmalloc(sizeof(*delnames) * n);
 
/* Copy, sort, and reject duplicate refs */
@@ -3429,7 +3428,7 @@ int commit_ref_transaction(struct ref_transaction 
*transaction,
   (update-have_old ?
update-old_sha1 : NULL),
   update-flags,
-  types[i], onerr);
+  update-type, onerr);
if (!update-lock) {
ret = 1;
goto cleanup;
@@ -3457,7 +3456,7 @@ int commit_ref_transaction(struct ref_transaction 
*transaction,
 
if (update-lock) {
delnames[delnum++] = update-lock-ref_name;
-   ret |= delete_ref_loose(update-lock, types[i]);
+   ret |= delete_ref_loose(update-lock, update-type);
}
}
 
@@ -3471,7 +3470,6 @@ cleanup:
if (updates[i]-lock)
unlock_ref(updates[i]-lock);
free(updates);
-   free(types);
free(delnames);
return ret;
 }
-- 
1.9.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


[PATCH 03/26] t1400: Pass a legitimate newvalue to update command

2014-03-10 Thread Michael Haggerty
This test is trying to test a few ways to delete references using git
update-ref -z --stdin.  The third line passed in is

update SP /refs/heads/c NUL NUL sha1 NUL

, which is not a correct way to delete a reference according to the
documentation (the new value should be zeros, not empty).  Pass zeros
instead as the new value to test the code correctly.

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 t/t1400-update-ref.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh
index 29391c6..e2f1dfa 100755
--- a/t/t1400-update-ref.sh
+++ b/t/t1400-update-ref.sh
@@ -927,7 +927,7 @@ test_expect_success 'stdin -z update refs fails with wrong 
old value' '
 test_expect_success 'stdin -z delete refs works with packed and loose refs' '
git pack-refs --all 
git update-ref $c $m~1 
-   printf $F delete $a $m update $b $Z $m update $c  $m~1 
stdin 
+   printf $F delete $a $m update $b $Z $m update $c $Z 
$m~1 stdin 
git update-ref -z --stdin stdin 
test_must_fail git rev-parse --verify -q $a 
test_must_fail git rev-parse --verify -q $b 
-- 
1.9.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 v2 2/2] i18n: assure command not corrupted by _() process

2014-03-10 Thread Sandy Carter

Is there any update on this patch?

Le 2014-03-03 09:55, Sandy Carter a écrit :

Separate message from command examples to avoid translation issues
such as a dash being omitted in a translation.

Signed-off-by: Sandy Carter sandy.car...@savoirfairelinux.com
---
  builtin/branch.c | 10 ++
  1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/builtin/branch.c b/builtin/branch.c
index b4d7716..b304da8 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -1022,11 +1022,13 @@ int cmd_branch(int argc, const char **argv, const char 
*prefix)
 */
if (argc == 1  track == BRANCH_TRACK_OVERRIDE 
!branch_existed  remote_tracking) {
-   fprintf(stderr, _(\nIf you wanted to make '%s' track '%s', do 
this:\n\n), head, branch-name);
-   fprintf(stderr, _(git branch -d %s\n), 
branch-name);
-   fprintf(stderr, _(git branch --set-upstream-to 
%s\n), branch-name);
+   fprintf(stderr, \n);
+   fprintf(stderr, _(If you wanted to make '%s' track '%s', do 
this:), head, branch-name);
+   fprintf(stderr, \n\n);
+   fprintf(stderr, git branch -d %s\n, branch-name);
+   fprintf(stderr, git branch --set-upstream-to %s\n, 
branch-name);
+   fprintf(stderr, \n);
}
-
} else
usage_with_options(builtin_branch_usage, options);



--
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: git merge --date --author

2014-03-10 Thread Yann Droneaud
Hi,

Le vendredi 07 mars 2014 à 11:43 -0800, Junio C Hamano a écrit :
 Andreas Schwab sch...@linux-m68k.org writes:
 
  Yann Droneaud ydrone...@opteya.com writes:
 
  But I'd like to know if there's a specific reason for git merge to not
  support --date and --author ?
 
  It's rather unusual that a merge is performed on behalf of a different
  author.
 
 Yes.  Michael's Nobody bothered to implement it is also correct
 but the reason why nobody bothered to most likely is due to why
 would you want to lie?.
 

When was Git changed in some kind of TSA agent one has to bribe to get
allowed to cross^Wcommit ? Why git lawyer is not implemented ? I want a
fair trial !

And before adding to Git a perfect lie detector (how will it able to
make the difference between truth and lie ? then, will it be able to
make the difference between good and bad ?, oh god, no !), I would
prefer to have it detect bugs before one could commit instead.

You seems to think I'm lying, but I'm not a liar: I just need to make
some arrangements with the history under another identity, as I could be
legally bound to. So it may sound like a lie for you, but ultimately,
it's the plain truth.

So as the tool is not in position to distinguish lie from truth, I'd
prefer to not see this concept brought here.

 If the use case is to rebuild history, you would need to be able to
 also lie about the committer, so
 
  git merge \
  --date 2013-12-31 23:59:59 + \
  --author Happy New Year happy.new-year@gregorian.calendar \
  current-year
 
 in such a history-rebuild script would not be sufficient.  The
 script can set necessary environment variables to lie about both
 author and commiter, though, of course.
 

Thanks for reminding this: I have to use GIT_COMMITER_DATE,
GIT_COMMITER_NAME and GIT_COMMITER_EMAIL.

As I'm not calling for adding --date and --author, I will continue to
use the environment variables: they're good enough for the job.

Regards.

-- 
Yann Droneaud
OPTEYA


--
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 21/26] struct ref_update: Store refname as a FLEX_ARRAY.

2014-03-10 Thread Michael Haggerty
Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 refs.c | 15 ++-
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/refs.c b/refs.c
index 5d08cdf..335d0e2 100644
--- a/refs.c
+++ b/refs.c
@@ -3274,11 +3274,11 @@ static int update_ref_write(const char *action, const 
char *refname,
  * value or to zero to ensure the ref does not exist before update.
  */
 struct ref_update {
-   const char *refname;
unsigned char new_sha1[20];
unsigned char old_sha1[20];
int flags; /* REF_NODEREF? */
int have_old; /* 1 if old_sha1 is valid, 0 otherwise */
+   const char refname[FLEX_ARRAY];
 };
 
 /*
@@ -3301,12 +3301,8 @@ void free_ref_transaction(struct ref_transaction 
*transaction)
 {
int i;
 
-   for (i = 0; i  transaction-nr; i++) {
-   struct ref_update *update = transaction-updates[i];
-
-   free((char *)update-refname);
-   free(update);
-   }
+   for (i = 0; i  transaction-nr; i++)
+   free(transaction-updates[i]);
 
free(transaction-updates);
free(transaction);
@@ -3315,9 +3311,10 @@ void free_ref_transaction(struct ref_transaction 
*transaction)
 static struct ref_update *add_update(struct ref_transaction *transaction,
 const char *refname)
 {
-   struct ref_update *update = xcalloc(1, sizeof(*update));
+   size_t len = strlen(refname);
+   struct ref_update *update = xcalloc(1, sizeof(*update) + len + 1);
 
-   update-refname = xstrdup(refname);
+   strcpy((char *)update-refname, refname);
ALLOC_GROW(transaction-updates, transaction-nr + 1, 
transaction-alloc);
transaction-updates[transaction-nr++] = update;
return update;
-- 
1.9.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


[PATCH 23/26] struct ref_update: Add a lock member

2014-03-10 Thread Michael Haggerty
Now that we manage ref_update objects internally, we can use them to
hold some of the scratch space we need when actually carrying out the
updates.  Store the (struct ref_lock *) there.

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 refs.c | 32 
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/refs.c b/refs.c
index ec638e9..73aec88 100644
--- a/refs.c
+++ b/refs.c
@@ -3278,6 +3278,7 @@ struct ref_update {
unsigned char old_sha1[20];
int flags; /* REF_NODEREF? */
int have_old; /* 1 if old_sha1 is valid, 0 otherwise */
+   struct ref_lock *lock;
const char refname[FLEX_ARRAY];
 };
 
@@ -3402,7 +3403,6 @@ int commit_ref_transaction(struct ref_transaction 
*transaction,
int ret = 0, delnum = 0, i;
struct ref_update **updates;
int *types;
-   struct ref_lock **locks;
const char **delnames;
int n = transaction-nr;
 
@@ -3412,7 +3412,6 @@ int commit_ref_transaction(struct ref_transaction 
*transaction,
/* Allocate work space */
updates = xmalloc(sizeof(*updates) * n);
types = xmalloc(sizeof(*types) * n);
-   locks = xcalloc(n, sizeof(*locks));
delnames = xmalloc(sizeof(*delnames) * n);
 
/* Copy, sort, and reject duplicate refs */
@@ -3426,12 +3425,12 @@ int commit_ref_transaction(struct ref_transaction 
*transaction,
for (i = 0; i  n; i++) {
struct ref_update *update = updates[i];
 
-   locks[i] = update_ref_lock(update-refname,
-  (update-have_old ?
-   update-old_sha1 : NULL),
-  update-flags,
-  types[i], onerr);
-   if (!locks[i]) {
+   update-lock = update_ref_lock(update-refname,
+  (update-have_old ?
+   update-old_sha1 : NULL),
+  update-flags,
+  types[i], onerr);
+   if (!update-lock) {
ret = 1;
goto cleanup;
}
@@ -3445,8 +3444,8 @@ int commit_ref_transaction(struct ref_transaction 
*transaction,
ret = update_ref_write(msg,
   update-refname,
   update-new_sha1,
-  locks[i], onerr);
-   locks[i] = NULL; /* freed by update_ref_write */
+  update-lock, onerr);
+   update-lock = NULL; /* freed by update_ref_write */
if (ret)
goto cleanup;
}
@@ -3454,9 +3453,11 @@ int commit_ref_transaction(struct ref_transaction 
*transaction,
 
/* Perform deletes now that updates are safely completed */
for (i = 0; i  n; i++) {
-   if (locks[i]) {
-   delnames[delnum++] = locks[i]-ref_name;
-   ret |= delete_ref_loose(locks[i], types[i]);
+   struct ref_update *update = updates[i];
+
+   if (update-lock) {
+   delnames[delnum++] = update-lock-ref_name;
+   ret |= delete_ref_loose(update-lock, types[i]);
}
}
 
@@ -3467,11 +3468,10 @@ int commit_ref_transaction(struct ref_transaction 
*transaction,
 
 cleanup:
for (i = 0; i  n; i++)
-   if (locks[i])
-   unlock_ref(locks[i]);
+   if (updates[i]-lock)
+   unlock_ref(updates[i]-lock);
free(updates);
free(types);
-   free(locks);
free(delnames);
return ret;
 }
-- 
1.9.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 05/26] t1400: Add some more tests involving quoted arguments

2014-03-10 Thread Johan Herland
On Mon, Mar 10, 2014 at 1:46 PM, Michael Haggerty mhag...@alum.mit.edu wrote:
 Previously there were no good tests of C-quoted arguments.

 Signed-off-by: Michael Haggerty mhag...@alum.mit.edu

FWIW, the first 5 patches seem trivially correct to me. Feel free to add:

Reviewed-by: Johan Herland jo...@herland.net

-- 
Johan Herland, jo...@herland.net
www.herland.net
--
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: question about: Facebook makes Mercurial faster than Git

2014-03-10 Thread Karsten Blees
Am 10.03.2014 12:42, schrieb Dennis Luehring:
 Am 10.03.2014 12:28, schrieb demerphq:
 I had the impression, and I would not be surprised if they had the
 impression that the git development community is relatively
 unconcerned about performance issues on larger repositories.
 
 so the question is if the git community is interested in beeing competive in 
 such
 large scale scenarios - something what mercurial seems to be now out of the 
 box
 

The hgwatchman site claims (https://bitbucket.org/facebook/hgwatchman)

On a real-world repository with over 200,000 files, hg status normally takes 
over 3 seconds. With hgwatchman it takes under 0.6 seconds.

There have been a few performance improvements in git status to support such 
large repositories. I just re-checked git status performance with the WebKit 
repo (~200k files):

Linux (with core.preloadIndex)
git status -uall: 0.620s
git status -uno : 0.255s

Windows (with core.preloadIndex and core.fscache)
git status -uall: 1.006s
git status -uno : 0.695s

Of course, for more reliable benchmark data, you'd have to compare the same 
repo on the same platform. But on first glance, it seems that mercurial with 
hgwatchman extension may be as fast as git is out of the box, not the other way 
around.

This comes at the cost of running a background daemon, which may slow down the 
entire system. E.g. if the daemon activates whenever the compiler creates a .o 
file, it will probably slow down build performance.

Note that hgwatchman doesn't support Windows, so git is probably much faster 
there.

--
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: [RFC/WIP] Pluggable reference backends

2014-03-10 Thread Shawn Pearce
On Mon, Mar 10, 2014 at 4:00 AM, Michael Haggerty mhag...@alum.mit.edu wrote:
 I have started working on pluggable ref backends.  In this email I
 would like to share my plans and solicit feedback.

Yay!

JGit already has pluggable ref backends, so it is good to see this
starting in git-core.

FWIW the Gerrit Code Review community is interested in this project.

 * Store references in a SQLite database, to get correct transaction
   handling.

No to SQLLite in git-core. Using it from JGit requires building
SQLLite and a JNI wrapper, which makes JGit significantly less
portable. I know SQLLite is pretty amazing, but implementing
compatibility with it from JGit will be a big nightmare for us.

 * Reference transactions that can be used across multiple Git
   commands.  Imagine,

   export GIT_TRANSACTION=$(git transaction begin)
   trap 'git transaction rollback' ERR
   git foo ...
   git bar ...
   git baz ...
   if ! git transaction commit
   then
   # Transaction failed; all references rolled back
   else
   # Transaction succeeded; all references updated atomically
   fi
   trap '' ERR
   unset GIT_TRANSACTION

   The GIT_TRANSACTION environment variable would tell git to read
   from the usual references, overridden with any reference changes
   that have occurred during the transaction, but write any changes
   (including both old and new values) to the transaction.  The command
   git transaction commit would verify that the old values listed in
   the transaction still agree with the current values, and then make
   all of the changes atomically.

Yay!

Gerrit Code Review really wants to get transactions implemented. So I
am very much in favor of trying to improve the situation in git-core.

We want not only a transaction over 2+ references in the same
repository, but we also want to perform transactions across
repositories. Consider a git submodule child and parent being updated
at the same time. We really want to update refs/heads/master in both
repositories atomically at the central server.

   Such transactions could also be broadcast to mirrors when they are
   committed to keep multiple Git repositories in sync.

Ooh, this would be very interesting.

 Git hosters [1] will be likely to take advantage of alternate
 reference backends pretty easily, because they know which tools touch
 their repositories and need only update those tools.  It is expected
 that alternate reference backends will be useful for hosters even if
 they don't become practical for end-users.

Alternate reference backends are absolutely useful to large hosters.
The loose reference format isn't very scalable. The packed-refs helps,
but you can do better. IIRC our android.googlesource.com reference
backend uses only 79 bytes per reference on average, including both
the name string and the value. This super compact format is easy to
hold in RAM for hundreds of busy repositories.

 For end-users it is important that their repository be readable by all
 of the tools that they use.  So if we want to make a new format a
 viable option for normal Git users (let alone make it the new default
 format), some coordination will be needed between all of the
 commonly-used Git implementations (git-core, libgit2, JGit, and maybe
 Dulwich, Grit, ...).  Whether or not this happens in real life depends
 on how advantageous the hypothetical new format is to Git users and is
 beyond the scope of this proposal.

It is sad we have this many implementations, but as one of the authors
(JGit) I am happy to at least see you are worrying about compatibility
with them.
--
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: question about: Facebook makes Mercurial faster than Git

2014-03-10 Thread Michael Haggerty
On 03/10/2014 01:10 PM, Johan Herland wrote:
 It should be possible to teach Git to do similar things, and IINM
 there are (and have previously been) several attempts to do similar
 things in Git, e.g.:
 
  - http://thread.gmane.org/gmane.comp.version-control.git/240339
 
  - http://thread.gmane.org/gmane.comp.version-control.git/217817
 
 I haven't looked closely at these attempts (it is not my scratch to
 itch), and I don't know if/how they would work on top of Watchman, but
 in principle I don't see why Git shouldn't be able to leverage
 Watchman the same way Mercurial does.

This touches on the most important thing that we should take to heart
from this episode:

Of course Facebook could have modified either Git or Mercurial to do
what they want.  Why did they pick Mercurial?  The article seems to
claim that they were initially biased towards Git, but they chose
Mercurial because its code base is easier to modify.  This is a claim
that I can easily believe.

The two projects are almost exactly the same age.  The number of commits
in the two projects is similar.  Mercurial has had fewer contributors
active at any given time over its project lifetime.

But let's see how much code is in the main part of Mercurial vs. Git:

$ find mercurial hgext \( -name '*.c' -o -name '*.py' \) -print |
  xargs cat | wc -l
46164

$ cat *.c *.h *.sh *.perl builtin/*.c | wc -l
188530

These are just crude estimates and I hope I got the right directories
for Mercurial.  But, by these numbers, Git has 4 times as much code as
Mercurial.  That alone will go a long way to making Git harder to
modify.  I don't think that Git has anywhere near 4 times the features
of Mercurial.  Probably most of the difference can be explained by the
choice of implementation languages; 94% of the code in these hg
directories is Python, whereas 88% of Git's core code is C.

How can we make Git easier to hack (short of switching languages)?  Here
are my suggestions:

* Better function docstrings -- don't make developers have to read the
whole call stack to find out what a function does, or who owns the
memory that is passed around.

* More modularity -- more coherent and abstract APIs between different
parts of the system, and less pawing around in your neighbor's data
structures.

* Higher-level abstractions -- make more use of APIs like strbuf and
string_list as opposed to handling every malloc() and realloc() by hand.

I personally wish that we as a project would be more willing to spend a
few extra CPU microseconds to make our code easier to read and modify
and more robust.

Michael

-- 
Michael Haggerty
mhag...@alum.mit.edu
http://softwareswirl.blogspot.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


Re: Trust issues with hooks and config files

2014-03-10 Thread Junio C Hamano
Julian Brost jul...@0x4a42.net writes:

 On 07.03.2014 22:04, Jeff King wrote:
 
 If you want to work on it, I think it's an interesting area. But
 any development would need to think about the transition plan for
 existing sites that will be broken.

 I can understand the problem with backward compatibility but in my
 opinion the default behavior should definitely be to ignore untrusted
 config files and hooks as it would otherwise only protect users that
 are already aware of the issue anyways and manually enable this option.

 Are there any plans for some major release in the future that would
 allow introducing backward incompatible changes?

Git 2.0 has been in the planning for quite some months, and I am
inclined to merge these topics prepared for that release to 'master'
during this cycle.  Anything new like this one is way too late for
it, but that does not mean we can never do 3.0 in the future.

Perhaps going this way might be possible:

 * Introduce a configuration that is read only from $HOME/.gitconfig
   (or its xdg equivalent) to enable or disable the unsafe behaviour.

   By default (i.e. when the above configuration is not set), allow
   unsafe read; when instructed by the above configuration to
   forbid unsafe read, ignore configuration files that are not
   owned by the owner of the process.  People can toggle the
   unsafe read to experiment with the above (~gitdaemon/.gitconfig
   can perhaps be used to restrict the daemon access)

   Keep it that way for a few releases.

 * After a few releases, start warning people who do not have the
   unsafe option in their $HOME/.gitconfig about a future default
   change, to force them to explicitly set it.

   Keep it that way for a few releases.

 * Flip the default, perhaps still keeping the warning on the
   flipped default to help people who have not been following along.

   Keep it that way for a few releases.

 * Then finally remove the warning.

A release cycle usually last 10-12 weeks on average.
--
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] upload-pack: send shallow info over stdin to pack-objects

2014-03-10 Thread Junio C Hamano
Duy Nguyen pclo...@gmail.com writes:

 On Sat, Mar 8, 2014 at 1:27 AM, Junio C Hamano gits...@pobox.com wrote:
 On the receive-pack side, the comment at the bottom of
 preprare_shallow_update() makes it clear that, if we wanted to use
 hooks, we cannot avoid having the proposed new shallow-file in a
 temporary file, which is unfortunate.  Do we have a similar issue on
 hooks on the upload-pack side?

 No. I don't think we have hooks on upload-pack.

 The question was not only about do we happen to work OK with the
 current code? but about are we closing the door for the future?

 If we ever need to add hooks to upload-pack, with the updated
 approach, its operation will not be affected by the temporary
 shallow file tailored for this specific customer.  Which I think is
 a good thing in general.

 But at the same time, it means that its operation cannot be
 customized for the specific customer, taking into account what they
 lack (which can be gleaned by looking at the temporary shallow
 information).  I do think that it is not a big downside, but that is
 merely my knee-jerk reaction.

 When upload-pack learns about hooks, I think we'll need to go back
 with --shallow-file, perhaps we a secure temporary place to write in.
 I don't see another way out. Not really sure why upload-pack needs
 customization though. The only case I can think of is to prevent most
 users from fetching certain objects, but that does not sound
 realistic..

I was more thinking along the lines of logging.

But you are right that we can easily revisit --shallow-file
interface later.

 Of course.. So what should we do with this? Go with this no temp
 file approach and deal with hooks when they come, or prepare now and
 introduce a secure temp. area?

I was rather hoping that we did not have to worry about temporary
files.  This patch solves the issue for the service people would
expect to be read-only the most, and it is a good step in the right
direction.  So let's follow through with the approach and not worry
about secure temporary for now.
--
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 v7 00/11] Add interpret-trailers builtin

2014-03-10 Thread Junio C Hamano
Øystein Walle oys...@gmail.com writes:

 Junio C Hamano gitster at pobox.com writes:

 
  ...
 
 is easier to read and maintain if written like so (with using HT
 properly---our MUAs may damage it and turn the indentation into
 spaces):
 
  ... 
  sed -e s/ Z$/ / expect -\EOF 
 Fixes: Z
 Acked-by= Z
 Reviewed-by: Z
 Signed-off-by: Z
  EOF
  ...
 

 How about:

printf '%s: \n' Fixes Acked-by Reviewed-by Signed-off-by  expect

Not really.

 This solution scores high marks in both readability and maintainability
 in my mind.

I actually considered that approach while I was writing the message
you responded to, but discarded it because it forces us to commit to
the view that we forsee no need to test an output that does not end
with a trailing whitespace.  And I do not think that is a limitation
we want to place on this test.

--
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/RFC] Documentation: Say that submodule clones use a separate gitdirs.

2014-03-10 Thread Junio C Hamano
Andrew Keller and...@kellerfarm.com writes:

 On Mar 7, 2014, at 7:50 PM, Henri GEIST wrote:
 ...
 To give one of my project to someone else I have copied it on a USB key.
 By a simple drag and drop with the mouse.
 And I am quite sure I am not alone doing this way.
 
 I have done those kind of things lot of time without any problem.
 But that day 'the_project' happened to be a submodule cloned by
 'git submodule update' then on the USB key the $GIT_DIR of 'the_project'
 was missing.
 
 If 'man git-submodule' have made me aware of the particularities of 
 submodules
 clone I had write in a terminal:
 
 git clone the_project /media/usb/the_project
 
 Or at least I had understand what happened quicker.
 
 I have nothing against also adding something in repository-layout but I am
 pretty sure normal users never read repository-layout as it is not a command
 they use. And it is not mentioned in most tutorials.

 How about something like this:

 The git directory of a submodule lives inside the git directory of the 
 parent repository instead of within the working directory.

 I'm not sure where to put it, though.

This is not limited to submodules.  There are multiple lower-level
mechanisms for a $path/.git to borrow the repository data from
elsewhere outside of $path and a cloned submodule uses only one of
them.  For any such $path, cp -R $path $otherplace will result in
an $otherplace that does not work as a Git repository in exactly
the same way, whether it happens to be a submodule checkout or not.

That is why I suggested to enhance description on a more general
part of the documentation that covers what a Git repository is.
--
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: [GSoC][PATCH v2] use strchrnul() in place of strchr() and strlen()

2014-03-10 Thread Junio C Hamano
Rohit Mani rohit.m...@outlook.com writes:

 Avoid scanning strings twice, once with strchr() and then with
 strlen(), by using strchrnul().

Thanks. The patch looks good.
--
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: [RFC/WIP] Pluggable reference backends

2014-03-10 Thread Max Horn

On 10.03.2014, at 15:30, Shawn Pearce spea...@spearce.org wrote:

 On Mon, Mar 10, 2014 at 4:00 AM, Michael Haggerty mhag...@alum.mit.edu 
 wrote:
 I have started working on pluggable ref backends.  In this email I
 would like to share my plans and solicit feedback.
 
 Yay!

Yay, too!

 JGit already has pluggable ref backends, so it is good to see this
 starting in git-core.
 
 FWIW the Gerrit Code Review community is interested in this project.
 
 * Store references in a SQLite database, to get correct transaction
  handling.
 
 No to SQLLite in git-core. Using it from JGit requires building
 SQLLite and a JNI wrapper, which makes JGit significantly less
 portable. I know SQLLite is pretty amazing, but implementing
 compatibility with it from JGit will be a big nightmare for us.

I understood this as an example (indeed, it is listed under Wile new ideas), 
not a proposal to put this into the git core. It might be an interesting 
experiment in any case, and if the proposed modularity is truly achieved, it 
could (if there was any interest in it, that is) be implemented in an external 
3rd party project.


Anyway, I am quite excited about this project. Usually, I am quite skeptical 
about such large scope ideas (Yeah, cool idea, but who will pull it off, and 
with which resources?). But this one seems to have a good chance of being 
implemented gradually and inside the main repository, with the help of feature 
flags. 

Thus, I am looking forward to Michael's announced initial patch series. I feel 
that I don't know enough yet about git overall to be of much help on my own at 
this point. But perhaps over time some mini- or micro-projects pop up were 
others can help (e.g. adapt these 50 tests to work with the 'quagga' ref); if 
they are pointed out (assuming that doing so isn't more work than just 
addressing them yourself ;-), I am willing to help out.


Cheers,
Max


signature.asc
Description: Message signed with OpenPGP using GPGMail


Re: [RFC/WIP] Pluggable reference backends

2014-03-10 Thread Jeff King
On Mon, Mar 10, 2014 at 07:30:45AM -0700, Shawn Pearce wrote:

  * Store references in a SQLite database, to get correct transaction
handling.
 
 No to SQLLite in git-core. Using it from JGit requires building
 SQLLite and a JNI wrapper, which makes JGit significantly less
 portable. I know SQLLite is pretty amazing, but implementing
 compatibility with it from JGit will be a big nightmare for us.

That seems like a poor reason not to implement a pluggable feature for
git-core. If we implement it, then a site using only git-core can take
advantage of it. Sites with JGit cannot, and would use a different
pluggable storage mechanism that's supported by both. But if we don't
implement, it hurts people using only git-core, and it does not help
sites using JGit at all.

That's assuming that attention spent on implementing the feature does
not take away from implementing some other parallel scheme that does the
same thing but does not use SQLite. I don't know what that would be
offhand; mapping the ref and reflog into a relational database is pretty
simple, and we get a lot of robustness and efficiency benefits for free.
We could perhaps have some kind of relational backend could use an
ODBC-like abstraction to point to a database. I have no idea if people
would want to ever store refs in a real server-backend RDBMS, but I
suspect Java has native support for such things.

Certainly I think we should aim for compatibility where we can, but if
there's not a compatible way to do something, I don't think the
limitations of one platform should drag other ones down. And that goes
both ways; we had to reimplement disk-compatible EWAH from scratch in C
for git-core to have bitmaps, whereas JGit just got to use a ready-made
library. I don't think that was a bad thing.  People in
mixed-implementation environments couldn't use it, but people with
JGit-only environments were free to take advantage of it.

At any rate, the repository needs to advertise this is the ref storage
mechanism I use in the config. We're going to need to bump
core.repositoryformatversion for such cases (because an old version of
git should not blindly lock and write to a refs/ directory that nobody
else is ever going to look at). And I'd suggest with that bump adding in
something like core.refstorage, so that an implementation can say
foobar ref storage? Never heard of it and barf. Whether it's because
that implementation doesn't support foobar, because it's an old
version that doesn't understand foobar yet, or because it was simply
built without foobar support.

-Peff
--
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: [RFC/WIP] Pluggable reference backends

2014-03-10 Thread David Kastrup
Jeff King p...@peff.net writes:

 On Mon, Mar 10, 2014 at 07:30:45AM -0700, Shawn Pearce wrote:

  * Store references in a SQLite database, to get correct transaction
handling.
 
 No to SQLLite in git-core. Using it from JGit requires building
 SQLLite and a JNI wrapper, which makes JGit significantly less
 portable. I know SQLLite is pretty amazing, but implementing
 compatibility with it from JGit will be a big nightmare for us.

 That seems like a poor reason not to implement a pluggable feature for
 git-core. If we implement it, then a site using only git-core can take
 advantage of it. Sites with JGit cannot, and would use a different
 pluggable storage mechanism that's supported by both. But if we don't
 implement, it hurts people using only git-core, and it does not help
 sites using JGit at all.

Of course, the basic premise for this feature is let's assume that our
file and/or operating system suck at providing file system functionality
at file name granularity.  There have been two historically approaches
to that problem that are not independent: a) use Linux b) kick Linus.

Option b) has been fairly successful over quite a bit of time, but at
the current point of time, it has become harder to aim that kick on a
single person and/or where it counts.

The database approach is an alternative approach based on kicking an
alternate set of people, namely database rather than operating system
providers, based on the assumption that the former have softer behinds
(the backend-based approach) making them more sensitive to kicking.

So the database approach is most promising on the what are we going to
do if our operating system vendor won't bother with sensible file system
performance angle.  Which isn't doing total system architecture a
favor.

Personally, I have little sympathy for helping subpar systems, keeping
them on life support while they are in turn trying to squish the better
systems.

But then it is not me doing the actual work, so this is no more than an
idle reflection.

-- 
David Kastrup
--
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: [RFC/WIP] Pluggable reference backends

2014-03-10 Thread David Lang

On Mon, 10 Mar 2014, David Kastrup wrote:


Jeff King p...@peff.net writes:


On Mon, Mar 10, 2014 at 07:30:45AM -0700, Shawn Pearce wrote:


* Store references in a SQLite database, to get correct transaction
  handling.


No to SQLLite in git-core. Using it from JGit requires building
SQLLite and a JNI wrapper, which makes JGit significantly less
portable. I know SQLLite is pretty amazing, but implementing
compatibility with it from JGit will be a big nightmare for us.


That seems like a poor reason not to implement a pluggable feature for
git-core. If we implement it, then a site using only git-core can take
advantage of it. Sites with JGit cannot, and would use a different
pluggable storage mechanism that's supported by both. But if we don't
implement, it hurts people using only git-core, and it does not help
sites using JGit at all.


Of course, the basic premise for this feature is let's assume that our
file and/or operating system suck at providing file system functionality
at file name granularity.  There have been two historically approaches
to that problem that are not independent: a) use Linux b) kick Linus.


As a note, if this is done properly, it could allow for plugins that connect to 
the underlying storage system (similar to the Facebook Mecurial change)


Even for those who don't have the $ storage arrays, there may be other 
storage specific hacks that can be done to detect that files haven't changed.


For example, with btrfs and you compile into a different directory thatn your 
source, you may be able to detect that things didn't change by the fact that the 
filesystem didn't have to do a rewrite of the parent node.


David Lang
--
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 03/26] t1400: Pass a legitimate newvalue to update command

2014-03-10 Thread Brad King
On 03/10/2014 08:46 AM, Michael Haggerty wrote:
 This test is trying to test a few ways to delete references using git
 update-ref -z --stdin.  The third line passed in is
 
 update SP /refs/heads/c NUL NUL sha1 NUL
 
 , which is not a correct way to delete a reference according to the
 documentation (the new value should be zeros, not empty).  Pass zeros
 instead as the new value to test the code correctly.

In my original work on this feature, an empty newvalue is allowed.
Since newvalue is not optional an empty value can be treated as zero.
The relevant documentation is:

 update::
 Set ref to newvalue after verifying oldvalue, if given.
 Specify a zero newvalue to ensure the ref does not exist

 ...

 Use 40 0 or the empty string to specify a zero value, except that
 with `-z` an empty oldvalue is considered missing.

The two together say that newvalue can be the empty string instead
of a literal zero.

-Brad
--
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 13/26] update-ref --stdin: Simplify error messages for missing oldvalues

2014-03-10 Thread Brad King
On 03/10/2014 01:08 PM, Brad King wrote:
 -die(update %s missing [oldvalue] NUL, update-ref_name);
 +die(update %s missing oldvalue, update-ref_name);
 
 The reason for the original wording is that the oldvalue is indeed
 optional.  This can only occur at end-of-input, and it is actually the
 *NUL* that is missing because an empty old value can be specified to
 mean that it it intentionally missing.

I see a following patch makes the wording even clearer about
unexpected end of input, so ignore my previous review.

-Brad

--
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 13/26] update-ref --stdin: Simplify error messages for missing oldvalues

2014-03-10 Thread Brad King
On 03/10/2014 08:46 AM, Michael Haggerty wrote:
 Instead of, for example,
 
 fatal: update refs/heads/master missing [oldvalue] NUL
 
 emit
 
 fatal: update refs/heads/master missing oldvalue
[snip]
 - die(update %s missing [oldvalue] NUL, update-ref_name);
 + die(update %s missing oldvalue, update-ref_name);

The reason for the original wording is that the oldvalue is indeed
optional.  This can only occur at end-of-input, and it is actually the
*NUL* that is missing because an empty old value can be specified to
mean that it it intentionally missing.

-Brad

--
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] clean: respect pathspecs with -d

2014-03-10 Thread Jeff King
git-clean uses read_directory to fill in a `struct dir` with
potential hits. However, read_directory does not actually
check against our pathspec. It uses a simplified version
that may turn up false positives. As a result, we need to
check that any hits match our pathspec. We do so reliably
for non-directories. For directories, if -d is not given
we check that the pathspec matched exactly (i.e., we are
even stricter, and require an explicit git clean foo to
clean foo/). But if -d is given, rather than relaxing
the exact match to allow a recursive match, we do not check
the pathspec at all.

This regression was introduced in 113f10f (Make git-clean a
builtin, 2007-11-11).

Signed-off-by: Jeff King p...@peff.net
---
On Mon, Mar 10, 2014 at 11:31:37AM +0100, Robin Pedersen wrote:

 I accidentially deleted a directory using git clean. I would think
 this is a bug, but I'm not sure. Was using 1.8.1, but upgraded to
 1.9.0 just to see if it was still reproducable, and it was.

Definitely a bug, and it dates back quite a while.  Thanks for a very
clear bug report.

-- 8 --
 builtin/clean.c  | 5 +++--
 t/t7300-clean.sh | 8 
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/builtin/clean.c b/builtin/clean.c
index 114d7bf..31c1488 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -947,14 +947,15 @@ int cmd_clean(int argc, const char **argv, const char 
*prefix)
if (pathspec.nr)
matches = dir_path_match(ent, pathspec, 0, NULL);
 
+   if (pathspec.nr  !matches)
+   continue;
+
if (S_ISDIR(st.st_mode)) {
if (remove_directories || (matches == MATCHED_EXACTLY)) 
{
rel = relative_path(ent-name, prefix, buf);
string_list_append(del_list, rel);
}
} else {
-   if (pathspec.nr  !matches)
-   continue;
rel = relative_path(ent-name, prefix, buf);
string_list_append(del_list, rel);
}
diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh
index 710be90..0c602de 100755
--- a/t/t7300-clean.sh
+++ b/t/t7300-clean.sh
@@ -511,4 +511,12 @@ test_expect_success SANITY 'git clean -d with an 
unreadable empty directory' '
! test -d foo
 '
 
+test_expect_success 'git clean -d respects pathspecs' '
+   mkdir foo 
+   mkdir foobar 
+   git clean -df foobar 
+   test_path_is_dir foo 
+   test_path_is_missing foobar
+'
+
 test_done
-- 
1.9.0.403.g7a2f4b0

--
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] clean: respect pathspecs with -d

2014-03-10 Thread Jeff King
On Mon, Mar 10, 2014 at 01:20:02PM -0400, Jeff King wrote:

 On Mon, Mar 10, 2014 at 11:31:37AM +0100, Robin Pedersen wrote:
 
  I accidentially deleted a directory using git clean. I would think
  this is a bug, but I'm not sure. Was using 1.8.1, but upgraded to
  1.9.0 just to see if it was still reproducable, and it was.
 
 Definitely a bug, and it dates back quite a while.  Thanks for a very
 clear bug report.
 
 -- 8 --

Whoops, accidentally included a scissors line here that will break
people using git am --scissors to pick up the patch. Here it is
correctly formatted.

-- 8 --
Subject: clean: respect pathspecs with -d

git-clean uses read_directory to fill in a `struct dir` with
potential hits. However, read_directory does not actually
check against our pathspec. It uses a simplified version
that may turn up false positives. As a result, we need to
check that any hits match our pathspec. We do so reliably
for non-directories. For directories, if -d is not given
we check that the pathspec matched exactly (i.e., we are
even stricter, and require an explicit git clean foo to
clean foo/). But if -d is given, rather than relaxing
the exact match to allow a recursive match, we do not check
the pathspec at all.

This regression was introduced in 113f10f (Make git-clean a
builtin, 2007-11-11).

Signed-off-by: Jeff King p...@peff.net
---
 builtin/clean.c  | 5 +++--
 t/t7300-clean.sh | 8 
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/builtin/clean.c b/builtin/clean.c
index 114d7bf..31c1488 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -947,14 +947,15 @@ int cmd_clean(int argc, const char **argv, const char 
*prefix)
if (pathspec.nr)
matches = dir_path_match(ent, pathspec, 0, NULL);
 
+   if (pathspec.nr  !matches)
+   continue;
+
if (S_ISDIR(st.st_mode)) {
if (remove_directories || (matches == MATCHED_EXACTLY)) 
{
rel = relative_path(ent-name, prefix, buf);
string_list_append(del_list, rel);
}
} else {
-   if (pathspec.nr  !matches)
-   continue;
rel = relative_path(ent-name, prefix, buf);
string_list_append(del_list, rel);
}
diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh
index 710be90..0c602de 100755
--- a/t/t7300-clean.sh
+++ b/t/t7300-clean.sh
@@ -511,4 +511,12 @@ test_expect_success SANITY 'git clean -d with an 
unreadable empty directory' '
! test -d foo
 '
 
+test_expect_success 'git clean -d respects pathspecs' '
+   mkdir foo 
+   mkdir foobar 
+   git clean -df foobar 
+   test_path_is_dir foo 
+   test_path_is_missing foobar
+'
+
 test_done
-- 
1.9.0.403.g7a2f4b0

--
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] clean: simplify dir/not-dir logic

2014-03-10 Thread Jeff King
On Mon, Mar 10, 2014 at 01:20:02PM -0400, Jeff King wrote:

 git-clean uses read_directory to fill in a `struct dir` with
 potential hits. However, read_directory does not actually
 check against our pathspec. It uses a simplified version
 that may turn up false positives. As a result, we need to
 check that any hits match our pathspec. We do so reliably
 for non-directories. For directories, if -d is not given
 we check that the pathspec matched exactly (i.e., we are
 even stricter, and require an explicit git clean foo to
 clean foo/). But if -d is given, rather than relaxing
 the exact match to allow a recursive match, we do not check
 the pathspec at all.
 
 This regression was introduced in 113f10f (Make git-clean a
 builtin, 2007-11-11).

The code has been cleaned up quite a bit from that original version, and
it was pretty easy to see the discrepancy between the two code paths.
However, if the code were structured like the cleanup patch below, I
think it would have been even easier.

This comes on top of my other patch. So the bug is already fixed, but I
think the end result is more readable.

-- 8 --
When we get a list of paths from read_directory, we further
prune it to create the final list of items to remove. The
code paths for directories and non-directories repeat the
same add to list code.

This patch restructures the code so that we don't repeat
ourselves. Also, by following a if (condition) continue
pattern like the pathspec check above, it makes it more
obvious that the conditional is about excluding directories
under certain circumstances.

Signed-off-by: Jeff King p...@peff.net
---
 builtin/clean.c | 15 ++-
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/builtin/clean.c b/builtin/clean.c
index 31c1488..cf76b1f 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -950,15 +950,12 @@ int cmd_clean(int argc, const char **argv, const char 
*prefix)
if (pathspec.nr  !matches)
continue;
 
-   if (S_ISDIR(st.st_mode)) {
-   if (remove_directories || (matches == MATCHED_EXACTLY)) 
{
-   rel = relative_path(ent-name, prefix, buf);
-   string_list_append(del_list, rel);
-   }
-   } else {
-   rel = relative_path(ent-name, prefix, buf);
-   string_list_append(del_list, rel);
-   }
+   if (S_ISDIR(st.st_mode)  !remove_directories 
+   matches != MATCHED_EXACTLY)
+   continue;
+
+   rel = relative_path(ent-name, prefix, buf);
+   string_list_append(del_list, rel);
}
 
if (interactive  del_list.nr  0)
-- 
1.9.0.403.g7a2f4b0

--
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/26] Clean up update-refs --stdin and implement ref_transaction

2014-03-10 Thread Brad King
Hi Michael,

This is excellent work.

I haven't reviewed every line of logic in detail but the changes
look correct at a high level.  The only exception is that the empty
newvalue is supposed to be accepted and treated as zero even in
--stdin -z mode.  See my response to that individual change.

On 03/10/2014 08:46 AM, Michael Haggerty wrote:
 The new API for dealing with reference transactions is
 
 ref_transaction *transaction = create_ref_transaction();
 queue_create_ref(transaction, refname, new_sha1, ...);
 queue_update_ref(transaction, refname, new_sha1, old_sha1, ...);
 queue_delete_ref(transaction, refname, old_sha1, ...);
 ...
 if (commit_ref_transaction(transaction, msg, ...))
 die(...);

The layout of this API looks good.

The name queue is not fully representative of the current behavior.
It implies that the order is meaningful but we currently allow at most
one update to a ref and sort them by refname.  Does your follow-up work
define behavior for multiple updates to one ref?  Can it collapse them
into a single update after checking internal consistency of the sequence?

 So most of the commits in this series are actually cleanups in
 builtin/update-ref.c.  I also spend some time making the error
 messages emitted by that command more uniform.

All good cleanups, thanks.

 Finally, now that refs.c owns the data structures for dealing with
 transactions, it is possible to make a few simplifications.

Yes, it is much nicer to keep the data structures private, especially
as it avoids the copy of the transaction made before sorting.

Thanks,
-Brad

--
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: [RFC/WIP] Pluggable reference backends

2014-03-10 Thread Junio C Hamano
Jeff King p...@peff.net writes:

 On Mon, Mar 10, 2014 at 07:30:45AM -0700, Shawn Pearce wrote:

  * Store references in a SQLite database, to get correct transaction
handling.
 
 No to SQLLite in git-core. Using it from JGit requires building
 SQLLite and a JNI wrapper, which makes JGit significantly less
 portable. I know SQLLite is pretty amazing, but implementing
 compatibility with it from JGit will be a big nightmare for us.

 That seems like a poor reason not to implement a pluggable feature for
 git-core. If we implement it, then a site using only git-core can take
 advantage of it. Sites with JGit cannot, and would use a different
 pluggable storage mechanism that's supported by both. But if we don't
 implement, it hurts people using only git-core, and it does not help
 sites using JGit at all.

We would need to eventually have at least one backend that we know
will play well with different Git implementations that matter
(namely, git-core, Jgit and libgit2) before the feature can be
widely adopted.

The first backend that is used while the plugging-interface is in
development can be anything and does not have to be one that
eventual ubiquitous one, however; as long as it is something that we
do not mind carrying it forever, along with that final reference
backend.  I take the objection from Shawn only as against making the
sqlite that final one.



--
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: [RFC/WIP] Pluggable reference backends

2014-03-10 Thread Jeff King
On Mon, Mar 10, 2014 at 10:46:01AM -0700, Junio C Hamano wrote:

  No to SQLLite in git-core. Using it from JGit requires building
  SQLLite and a JNI wrapper, which makes JGit significantly less
  portable. I know SQLLite is pretty amazing, but implementing
  compatibility with it from JGit will be a big nightmare for us.
 
  That seems like a poor reason not to implement a pluggable feature for
  git-core. If we implement it, then a site using only git-core can take
  advantage of it. Sites with JGit cannot, and would use a different
  pluggable storage mechanism that's supported by both. But if we don't
  implement, it hurts people using only git-core, and it does not help
  sites using JGit at all.
 
 We would need to eventually have at least one backend that we know
 will play well with different Git implementations that matter
 (namely, git-core, Jgit and libgit2) before the feature can be
 widely adopted.

I assumed that the current refs/ and logs/ code, massaged into pluggable
backend form, would be the first such. And I wouldn't be surprised to
see some iteration on that once it is easier to move from scheme to
scheme (e.g., to use some encoding of the names on the filesystem to
avoid D/F conflicts, and thus allow reflogs for deleted refs).

 The first backend that is used while the plugging-interface is in
 development can be anything and does not have to be one that
 eventual ubiquitous one, however; as long as it is something that we
 do not mind carrying it forever, along with that final reference
 backend.  I take the objection from Shawn only as against making the
 sqlite that final one.

Sure, I'd agree with that. I'd think something like an sqlite interface
would be mainly of interest to people running busy servers. I don't know
that it would make a good default.

-Peff
--
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: question about: Facebook makes Mercurial faster than Git

2014-03-10 Thread David Lang

On Mon, 10 Mar 2014, Ondřej Bílka wrote:


On Mon, Mar 10, 2014 at 03:13:45AM -0700, David Lang wrote:

On Mon, 10 Mar 2014, Dennis Luehring wrote:


according to these blog posts

http://www.infoq.com/news/2014/01/facebook-scaling-hg
https://code.facebook.com/posts/218678814984400/scaling-mercurial-at-facebook/

mercurial can be faster then git

but i don't found any reply from the git community if it is a real problem
or if there a ongoing (maybe git 2.0) changes to compete better in this case


As I understand this, the biggest part of what happened is that
Facebook made a tweak to mercurial so that when it needs to know
what files have changed in their massive tree, their version asks
their special storage array, while git would have to look at it
through the filesystem interface (by doing stat calls on the
directories and files to see if anything has changed)


That is mostly a kernel problem. Long ago there was proposed patch to
add a recursive mtime so you could check what subtrees changed. If
somebody ressurected that patch it would gave similar boost.


btrfs could actually implement this efficiently, but for a lot of other 
filesysems this could be very expensive. The question is if it could be enough 
of a win to make it a good choice for people who are doing a heavy git workload 
as opposed to more generic uses.


there's also the issue of managed vs generated files, if you update the mtime 
all the way up the tree because a source file was compiled and a binary created, 
that will quickly defeat the value of the recursive mtime.


David Lang


There are two issues that need to be handled, first if you are concerned
about one mtime change doing lot of updates a application needs to mark
all directories it is interested on, when we do update we unmark
directory and by that we update each directory at most once per
application run.

Second problem were hard links where probably a best course is keep list
of these and stat them separately.

Re: question about: Facebook makes Mercurial faster than Git

2014-03-10 Thread Ondřej Bílka
On Mon, Mar 10, 2014 at 03:13:45AM -0700, David Lang wrote:
 On Mon, 10 Mar 2014, Dennis Luehring wrote:
 
 according to these blog posts
 
 http://www.infoq.com/news/2014/01/facebook-scaling-hg
 https://code.facebook.com/posts/218678814984400/scaling-mercurial-at-facebook/
 
 mercurial can be faster then git
 
 but i don't found any reply from the git community if it is a real problem
 or if there a ongoing (maybe git 2.0) changes to compete better in this case
 
 As I understand this, the biggest part of what happened is that
 Facebook made a tweak to mercurial so that when it needs to know
 what files have changed in their massive tree, their version asks
 their special storage array, while git would have to look at it
 through the filesystem interface (by doing stat calls on the
 directories and files to see if anything has changed)
 
That is mostly a kernel problem. Long ago there was proposed patch to
add a recursive mtime so you could check what subtrees changed. If
somebody ressurected that patch it would gave similar boost.

There are two issues that need to be handled, first if you are concerned
about one mtime change doing lot of updates a application needs to mark
all directories it is interested on, when we do update we unmark
directory and by that we update each directory at most once per
application run.

Second problem were hard links where probably a best course is keep list
of these and stat them separately.
--
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 5/7] merge: fix GIT_EDITOR override for commit hook

2014-03-10 Thread Benoit Pierre
Don't set GIT_EDITOR to : when calling prepare-commit-msg hook if the
editor is going to be called (e.g. with merge -e).

Signed-off-by: Benoit Pierre benoit.pie...@gmail.com
---
 builtin/merge.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/builtin/merge.c b/builtin/merge.c
index 67f312d..b11a528 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -821,7 +821,7 @@ static void prepare_to_commit(struct commit_list 
*remoteheads)
if (0  option_edit)
strbuf_commented_addf(msg, _(merge_editor_comment), 
comment_line_char);
write_merge_msg(msg);
-   if (run_commit_hook(1, get_index_file(), prepare-commit-msg,
+   if (run_commit_hook(0  option_edit, get_index_file(), 
prepare-commit-msg,
git_path(MERGE_MSG), merge, NULL))
abort_commit(remoteheads, NULL);
if (0  option_edit) {
-- 
1.9.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


[PATCH 7/7] run-command: mark run_hook_with_custom_index as deprecated

2014-03-10 Thread Benoit Pierre
---
 run-command.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/run-command.h b/run-command.h
index 88460f9..3653bfa 100644
--- a/run-command.h
+++ b/run-command.h
@@ -51,6 +51,7 @@ extern int run_hook_le(const char *const *env, const char 
*name, ...);
 extern int run_hook_ve(const char *const *env, const char *name, va_list args);
 
 LAST_ARG_MUST_BE_NULL
+__attribute__((deprecated))
 extern int run_hook_with_custom_index(const char *index_file, const char 
*name, ...);
 
 #define RUN_COMMAND_NO_STDIN 1
-- 
1.9.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


[PATCH 2/7] merge hook tests: use 'test_must_fail' instead of '!'

2014-03-10 Thread Benoit Pierre
Signed-off-by: Benoit Pierre benoit.pie...@gmail.com
---
 t/t7505-prepare-commit-msg-hook.sh | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/t/t7505-prepare-commit-msg-hook.sh 
b/t/t7505-prepare-commit-msg-hook.sh
index 1c95652..5531abb 100755
--- a/t/t7505-prepare-commit-msg-hook.sh
+++ b/t/t7505-prepare-commit-msg-hook.sh
@@ -154,7 +154,7 @@ test_expect_success 'with failing hook' '
head=`git rev-parse HEAD` 
echo more  file 
git add file 
-   ! GIT_EDITOR=\\$FAKE_EDITOR\ git commit -c $head
+   test_must_fail env GIT_EDITOR=\\$FAKE_EDITOR\ git commit -c $head
 
 '
 
@@ -163,7 +163,7 @@ test_expect_success 'with failing hook (--no-verify)' '
head=`git rev-parse HEAD` 
echo more  file 
git add file 
-   ! GIT_EDITOR=\\$FAKE_EDITOR\ git commit --no-verify -c $head
+   test_must_fail env GIT_EDITOR=\\$FAKE_EDITOR\ git commit 
--no-verify -c $head
 
 '
 
-- 
1.9.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


[PATCH V2 0/7] fix hunk editing with 'commit -p -m'

2014-03-10 Thread Benoit Pierre
This patch fixes the fact that hunk editing with 'commit -p -m' does not work:
GIT_EDITOR is set to ':' to indicate to hooks that no editor will be launched,
which result in the 'hunk edit' option not launching the editor (and selecting
the whole hunk).

The fix consists in deferring the GIT_EDITOR override to the hook subprocess,
like it's already done for GIT_INDEX_FILE:
- rename 'run_hook' to 'run_hook_le' and change the first parameter to the 
environment to set
- add a 'run_hook_ve' variant that take a va_list
- add a new 'run_commit_hook' helper (to set both GIT_EDITOR and GIT_INDEX_FILE)
- the old 'run_hook' functionality is available as 'run_hook_with_custom_index'
  (and marked as deprecated in the last optional patch of this series)

N.B.: the merge builtin 'prepare-commit-msg' hook handling has also been updated
to be consistent; i.e. GIT_EDITOR will not be set to ':' if the '--edit' option
is used.

Benoit Pierre (7):
  merge hook tests: fix missing '' in test
  merge hook tests: use 'test_must_fail' instead of '!'
  test patch hunk editing with commit -p -m
  commit: fix patch hunk editing with commit -p -m
  merge: fix GIT_EDITOR override for commit hook
  merge hook tests: fix and update tests
  run-command: mark run_hook_with_custom_index as deprecated

 builtin/checkout.c |  8 +++
 builtin/clone.c|  4 ++--
 builtin/commit.c   | 35 --
 builtin/gc.c   |  2 +-
 builtin/merge.c|  6 +++---
 commit.h   |  3 +++
 run-command.c  | 44 +++---
 run-command.h  |  7 +-
 t/t7505-prepare-commit-msg-hook.sh | 33 
 t/t7513-commit_-p_-m_hunk_edit.sh  | 34 +
 10 files changed, 137 insertions(+), 39 deletions(-)
 create mode 100755 t/t7513-commit_-p_-m_hunk_edit.sh

-- 
1.9.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


[PATCH 6/7] merge hook tests: fix and update tests

2014-03-10 Thread Benoit Pierre
- update 'no editor' hook test and add 'editor' hook test
- make sure the tree is reset to a clean state after running a test
  (using test_when_finished) so later tests are not impacted

Signed-off-by: Benoit Pierre benoit.pie...@gmail.com
---
 t/t7505-prepare-commit-msg-hook.sh | 27 +--
 1 file changed, 21 insertions(+), 6 deletions(-)

diff --git a/t/t7505-prepare-commit-msg-hook.sh 
b/t/t7505-prepare-commit-msg-hook.sh
index 5531abb..03dce09 100755
--- a/t/t7505-prepare-commit-msg-hook.sh
+++ b/t/t7505-prepare-commit-msg-hook.sh
@@ -134,14 +134,26 @@ test_expect_success 'with hook (-c)' '
 
 test_expect_success 'with hook (merge)' '
 
-   head=`git rev-parse HEAD` 
-   git checkout -b other HEAD@{1} 
-   echo more  file 
+   test_when_finished git checkout -f master 
+   git checkout -B other HEAD@{1} 
+   echo more file 
+   git add file 
+   git commit -m other 
+   git checkout - 
+   git merge --no-ff other 
+   test `git log -1 --pretty=format:%s` = merge (no editor)
+'
+
+test_expect_success 'with hook and editor (merge)' '
+
+   test_when_finished git checkout -f master 
+   git checkout -B other HEAD@{1} 
+   echo more file 
git add file 
git commit -m other 
git checkout - 
-   git merge other 
-   test `git log -1 --pretty=format:%s` = merge
+   env GIT_EDITOR=\\$FAKE_EDITOR\ git merge --no-ff -e other 
+   test `git log -1 --pretty=format:%s` = merge
 '
 
 cat  $HOOK 'EOF'
@@ -151,6 +163,7 @@ EOF
 
 test_expect_success 'with failing hook' '
 
+   test_when_finished git checkout -f master 
head=`git rev-parse HEAD` 
echo more  file 
git add file 
@@ -160,6 +173,7 @@ test_expect_success 'with failing hook' '
 
 test_expect_success 'with failing hook (--no-verify)' '
 
+   test_when_finished git checkout -f master 
head=`git rev-parse HEAD` 
echo more  file 
git add file 
@@ -169,6 +183,7 @@ test_expect_success 'with failing hook (--no-verify)' '
 
 test_expect_success 'with failing hook (merge)' '
 
+   test_when_finished git checkout -f master 
git checkout -B other HEAD@{1} 
echo more  file 
git add file 
@@ -178,7 +193,7 @@ test_expect_success 'with failing hook (merge)' '
exit 1
EOF
git checkout - 
-   test_must_fail git merge other
+   test_must_fail git merge --no-ff other
 
 '
 
-- 
1.9.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


[PATCH 3/7] test patch hunk editing with commit -p -m

2014-03-10 Thread Benoit Pierre
Add (failing) test: with commit changing the environment to let hooks
now that no editor will be used (by setting GIT_EDITOR to :), the
edit hunk functionality does not work (no editor is launched and the
whole hunk is committed).

Signed-off-by: Benoit Pierre benoit.pie...@gmail.com
---
 t/t7513-commit_-p_-m_hunk_edit.sh | 34 ++
 1 file changed, 34 insertions(+)
 create mode 100755 t/t7513-commit_-p_-m_hunk_edit.sh

diff --git a/t/t7513-commit_-p_-m_hunk_edit.sh 
b/t/t7513-commit_-p_-m_hunk_edit.sh
new file mode 100755
index 000..994939a
--- /dev/null
+++ b/t/t7513-commit_-p_-m_hunk_edit.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+test_description='hunk edit with commit -p -m'
+. ./test-lib.sh
+
+if ! test_have_prereq PERL
+then
+   skip_all=skipping '$test_description' tests, perl not available
+   test_done
+fi
+
+test_expect_success 'setup (initial)' '
+   echo line1 file 
+   git add file 
+   git commit -m commit1 
+   echo line3 file 
+   cat expect -\EOF
+   diff --git a/file b/file
+   index a29bdeb..c0d0fb4 100644
+   --- a/file
+   +++ b/file
+   @@ -1 +1,2 @@
+line1
+   +line2
+   EOF
+'
+
+test_expect_failure 'edit hunk commit -p -m message' '
+   echo e | env GIT_EDITOR=sed s/+line3\$/+line2/ -i git commit -p -m 
commit2 file 
+   git diff HEAD^ HEAD actual 
+   test_cmp expect actual
+'
+
+test_done
-- 
1.9.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


[PATCH 4/7] commit: fix patch hunk editing with commit -p -m

2014-03-10 Thread Benoit Pierre
Don't change git environment: move the GIT_EDITOR=: override to the
hook command subprocess, like it's already done for GIT_INDEX_FILE.

Signed-off-by: Benoit Pierre benoit.pie...@gmail.com
---
 builtin/checkout.c|  8 +++
 builtin/clone.c   |  4 ++--
 builtin/commit.c  | 35 ---
 builtin/gc.c  |  2 +-
 builtin/merge.c   |  6 +++---
 commit.h  |  3 +++
 run-command.c | 44 ---
 run-command.h |  6 +-
 t/t7513-commit_-p_-m_hunk_edit.sh |  2 +-
 9 files changed, 79 insertions(+), 31 deletions(-)

diff --git a/builtin/checkout.c b/builtin/checkout.c
index 5df3837..da423b2 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -53,10 +53,10 @@ struct checkout_opts {
 static int post_checkout_hook(struct commit *old, struct commit *new,
  int changed)
 {
-   return run_hook(NULL, post-checkout,
-   sha1_to_hex(old ? old-object.sha1 : null_sha1),
-   sha1_to_hex(new ? new-object.sha1 : null_sha1),
-   changed ? 1 : 0, NULL);
+return run_hook_le(NULL, post-checkout,
+  sha1_to_hex(old ? old-object.sha1 : null_sha1),
+  sha1_to_hex(new ? new-object.sha1 : null_sha1),
+  changed ? 1 : 0, NULL);
/* new can be NULL when checking out from the index before
   a commit exists. */
 
diff --git a/builtin/clone.c b/builtin/clone.c
index 43e772c..9b3c04d 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -660,8 +660,8 @@ static int checkout(void)
commit_locked_index(lock_file))
die(_(unable to write new index file));
 
-   err |= run_hook(NULL, post-checkout, sha1_to_hex(null_sha1),
-   sha1_to_hex(sha1), 1, NULL);
+   err |= run_hook_le(NULL, post-checkout, sha1_to_hex(null_sha1),
+  sha1_to_hex(sha1), 1, NULL);
 
if (!err  option_recursive)
err = run_command_v_opt(argv_submodule, RUN_GIT_CMD);
diff --git a/builtin/commit.c b/builtin/commit.c
index 3767478..baf1fc0 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -612,7 +612,7 @@ static int prepare_to_commit(const char *index_file, const 
char *prefix,
/* This checks and barfs if author is badly specified */
determine_author_info(author_ident);
 
-   if (!no_verify  run_hook(index_file, pre-commit, NULL))
+   if (!no_verify  run_commit_hook(use_editor, index_file, pre-commit, 
NULL))
return 0;
 
if (squash_message) {
@@ -866,8 +866,8 @@ static int prepare_to_commit(const char *index_file, const 
char *prefix,
return 0;
}
 
-   if (run_hook(index_file, prepare-commit-msg,
-git_path(commit_editmsg), hook_arg1, hook_arg2, NULL))
+   if (run_commit_hook(use_editor, index_file, prepare-commit-msg,
+   git_path(commit_editmsg), hook_arg1, hook_arg2, 
NULL))
return 0;
 
if (use_editor) {
@@ -883,7 +883,7 @@ static int prepare_to_commit(const char *index_file, const 
char *prefix,
}
 
if (!no_verify 
-   run_hook(index_file, commit-msg, git_path(commit_editmsg), NULL)) 
{
+   run_commit_hook(use_editor, index_file, commit-msg, 
git_path(commit_editmsg), NULL)) {
return 0;
}
 
@@ -1067,8 +1067,6 @@ static int parse_and_validate_options(int argc, const 
char *argv[],
use_editor = 0;
if (0 = edit_flag)
use_editor = edit_flag;
-   if (!use_editor)
-   setenv(GIT_EDITOR, :, 1);
 
/* Sanity check options */
if (amend  !current_head)
@@ -1445,6 +1443,29 @@ static int run_rewrite_hook(const unsigned char *oldsha1,
return finish_command(proc);
 }
 
+int run_commit_hook(int editor_is_used, const char *index_file, const char 
*name, ...)
+{
+   const char *hook_env[3] =  { NULL };
+   char index[PATH_MAX];
+   va_list args;
+   int ret;
+
+   snprintf(index, sizeof(index), GIT_INDEX_FILE=%s, index_file);
+   hook_env[0] = index;
+
+   /*
+* Let the hook know that no editor will be launched.
+*/
+   if (!editor_is_used)
+   hook_env[1] = GIT_EDITOR=:;
+
+   va_start(args, name);
+   ret = run_hook_ve(hook_env, name, args);
+   va_end(args);
+
+   return ret;
+}
+
 int cmd_commit(int argc, const char **argv, const char *prefix)
 {
static struct wt_status s;
@@ -1669,7 +1690,7 @@ int cmd_commit(int argc, const char **argv, const char 
*prefix)
 not exceeded, and then \git reset HEAD\ to recover.));
 
rerere(0);
-   run_hook(get_index_file(), post-commit, NULL);
+   run_commit_hook(use_editor, 

[PATCH 1/7] merge hook tests: fix missing '' in test

2014-03-10 Thread Benoit Pierre
Signed-off-by: Benoit Pierre benoit.pie...@gmail.com
---
 t/t7505-prepare-commit-msg-hook.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/t/t7505-prepare-commit-msg-hook.sh 
b/t/t7505-prepare-commit-msg-hook.sh
index 3573751..1c95652 100755
--- a/t/t7505-prepare-commit-msg-hook.sh
+++ b/t/t7505-prepare-commit-msg-hook.sh
@@ -174,7 +174,7 @@ test_expect_success 'with failing hook (merge)' '
git add file 
rm -f $HOOK 
git commit -m other 
-   write_script $HOOK -EOF
+   write_script $HOOK -EOF 
exit 1
EOF
git checkout - 
-- 
1.9.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/RFC] Documentation: Say that submodule clones use a separate gitdirs.

2014-03-10 Thread Henri GEIST
Le lundi 10 mars 2014 à 08:31 -0700, Junio C Hamano a écrit :
 Andrew Keller and...@kellerfarm.com writes:
 
  On Mar 7, 2014, at 7:50 PM, Henri GEIST wrote:
  ...
  To give one of my project to someone else I have copied it on a USB key.
  By a simple drag and drop with the mouse.
  And I am quite sure I am not alone doing this way.
  
  I have done those kind of things lot of time without any problem.
  But that day 'the_project' happened to be a submodule cloned by
  'git submodule update' then on the USB key the $GIT_DIR of 'the_project'
  was missing.
  
  If 'man git-submodule' have made me aware of the particularities of 
  submodules
  clone I had write in a terminal:
  
  git clone the_project /media/usb/the_project
  
  Or at least I had understand what happened quicker.
  
  I have nothing against also adding something in repository-layout but I am
  pretty sure normal users never read repository-layout as it is not a 
  command
  they use. And it is not mentioned in most tutorials.
 
  How about something like this:
 
  The git directory of a submodule lives inside the git directory of the 
  parent repository instead of within the working directory.
 
  I'm not sure where to put it, though.
 
 This is not limited to submodules.  There are multiple lower-level
 mechanisms for a $path/.git to borrow the repository data from
 elsewhere outside of $path and a cloned submodule uses only one of
 them.  For any such $path, cp -R $path $otherplace will result in
 an $otherplace that does not work as a Git repository in exactly
 the same way, whether it happens to be a submodule checkout or not.
 
 That is why I suggested to enhance description on a more general
 part of the documentation that covers what a Git repository is.

You are entirely right.
My view of the situation was biased by the fact that submodule cloning
is the only case I am aware of except when the user manually type
'--separate-git-dir' where this problem could occur.

If there is some other situation where this can occur as a side effect
of a git command it can be good to have the user aware of the list or
at least inform them in general case a git repository cannot be copied
in a place every body will see.
Or place a note in the manpage of every git command which can have this
side effect.




signature.asc
Description: This is a digitally signed message part


[PATCH][GSOC2014] changed logical chain in branch.c to lookup tables

2014-03-10 Thread TamerTas

Signed-off-by: TamerTas tamer...@outlook.com
---
 branch.c |   31 ---
 1 file changed, 8 insertions(+), 23 deletions(-)

diff --git a/branch.c b/branch.c
index 723a36b..397edd3 100644
--- a/branch.c
+++ b/branch.c
@@ -50,6 +50,9 @@ static int should_setup_rebase(const char *origin)
 void install_branch_config(int flag, const char *local, const char *origin, 
const char *remote)
 {
const char *shortname = remote + 11;
+   const char *location[] = {local, remote};
+   const char *type[] = {branch, ref};
+
int remote_is_branch = starts_with(remote, refs/heads/);
struct strbuf key = STRBUF_INIT;
int rebasing = should_setup_rebase(origin);
@@ -77,29 +80,11 @@ void install_branch_config(int flag, const char *local, 
const char *origin, cons
strbuf_release(key);
 
if (flag  BRANCH_CONFIG_VERBOSE) {
-   if (remote_is_branch  origin)
-   printf_ln(rebasing ?
- _(Branch %s set up to track remote branch %s 
from %s by rebasing.) :
- _(Branch %s set up to track remote branch %s 
from %s.),
- local, shortname, origin);
-   else if (remote_is_branch  !origin)
-   printf_ln(rebasing ?
- _(Branch %s set up to track local branch %s 
by rebasing.) :
- _(Branch %s set up to track local branch 
%s.),
- local, shortname);
-   else if (!remote_is_branch  origin)
-   printf_ln(rebasing ?
- _(Branch %s set up to track remote ref %s by 
rebasing.) :
- _(Branch %s set up to track remote ref %s.),
- local, remote);
-   else if (!remote_is_branch  !origin)
-   printf_ln(rebasing ?
- _(Branch %s set up to track local ref %s by 
rebasing.) :
- _(Branch %s set up to track local ref %s.),
- local, remote);
-   else
-   die(BUG: impossible combination of %d and %p,
-   remote_is_branch, origin);
+
+printf_ln(rebasing ?
+  _(Branch %s set up to track %s %s %s by rebasing.) :
+  _(Branch %s set up to track %s %s %s.),
+  local, location[!origin], type[remote_is_branch], remote);
}
 }
 
-- 
1.7.9.5

--
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][GSOC2014]

2014-03-10 Thread TamerTas
I inspected branch.c:install_branch_config() and since
the conditionals cover all the possibilities, I decided
that making the code table-driven would be much cleaner
and shorter. I've ran the tests and they all passed. 
Reimplementation using git am also didn't have any problems.
Please let me know if there is any problems that I missed.
I would also love to learn if you think that the code was better
before and why it was better.

TamerTas (1):
  changed logical chain in branch.c to lookup tables

 branch.c |   31 ---
 1 file changed, 8 insertions(+), 23 deletions(-)

-- 
1.7.9.5

--
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/2] status: allow NULL fmt for status_printf/status_vprintf_ln

2014-03-10 Thread Benoit Pierre
Useful for calling status_printf only to change/reset the color (and
output an additional '\n' with status_vprintf_ln).

Signed-off-by: Benoit Pierre benoit.pie...@gmail.com
---
 wt-status.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/wt-status.c b/wt-status.c
index 4e55810..17f63a4 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -49,7 +49,8 @@ static void status_vprintf(struct wt_status *s, int at_bol, 
const char *color,
struct strbuf linebuf = STRBUF_INIT;
const char *line, *eol;
 
-   strbuf_vaddf(sb, fmt, ap);
+   if (NULL != fmt)
+   strbuf_vaddf(sb, fmt, ap);
if (!sb.len) {
if (s-display_comment_prefix) {
strbuf_addch(sb, comment_line_char);
-- 
1.9.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


[PATCH 0/2] fix status_printf_ln calls zero-length format warnings

2014-03-10 Thread Benoit Pierre
Those happens with gcc -Wformat-zero-length. Since passing NULL does not
generate a warning (as __attribute__((printf())) does not imply nonull), modify
status_printf/status_printf_ln to allow a NULL format and update calls with an
empty string.

Benoit Pierre (2):
  status: allow NULL fmt for status_printf/status_vprintf_ln
  fix status_printf_ln calls zero-length format warnings

 builtin/commit.c |  2 +-
 wt-status.c  | 23 ---
 2 files changed, 13 insertions(+), 12 deletions(-)

-- 
1.9.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


[PATCH 2/2] fix status_printf_ln calls zero-length format warnings

2014-03-10 Thread Benoit Pierre
Those happens with gcc -Wformat-zero-length.

Change empty strings to NULL now that it's allowed.

Signed-off-by: Benoit Pierre benoit.pie...@gmail.com
---
 builtin/commit.c |  2 +-
 wt-status.c  | 20 ++--
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/builtin/commit.c b/builtin/commit.c
index 3767478..6d19439 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -805,7 +805,7 @@ static int prepare_to_commit(const char *index_file, const 
char *prefix,
committer_ident.buf);
 
if (ident_shown)
-   status_printf_ln(s, GIT_COLOR_NORMAL, );
+   status_printf_ln(s, GIT_COLOR_NORMAL, NULL);
 
saved_color_setting = s-use_color;
s-use_color = 0;
diff --git a/wt-status.c b/wt-status.c
index 17f63a4..d9b1d00 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -189,7 +189,7 @@ static void wt_status_print_unmerged_header(struct 
wt_status *s)
} else {
status_printf_ln(s, c, _(  (use \git add/rm file...\ as 
appropriate to mark resolution)));
}
-   status_printf_ln(s, c, );
+   status_printf_ln(s, c, NULL);
 }
 
 static void wt_status_print_cached_header(struct wt_status *s)
@@ -205,7 +205,7 @@ static void wt_status_print_cached_header(struct wt_status 
*s)
status_printf_ln(s, c, _(  (use \git reset %s file...\ to 
unstage)), s-reference);
else
status_printf_ln(s, c, _(  (use \git rm --cached file...\ 
to unstage)));
-   status_printf_ln(s, c, );
+   status_printf_ln(s, c, NULL);
 }
 
 static void wt_status_print_dirty_header(struct wt_status *s,
@@ -224,7 +224,7 @@ static void wt_status_print_dirty_header(struct wt_status 
*s,
status_printf_ln(s, c, _(  (use \git checkout -- file...\ to 
discard changes in working directory)));
if (has_dirty_submodules)
status_printf_ln(s, c, _(  (commit or discard the untracked or 
modified content in submodules)));
-   status_printf_ln(s, c, );
+   status_printf_ln(s, c, NULL);
 }
 
 static void wt_status_print_other_header(struct wt_status *s,
@@ -236,12 +236,12 @@ static void wt_status_print_other_header(struct wt_status 
*s,
if (!s-hints)
return;
status_printf_ln(s, c, _(  (use \git %s file...\ to include in 
what will be committed)), how);
-   status_printf_ln(s, c, );
+   status_printf_ln(s, c, NULL);
 }
 
 static void wt_status_print_trailer(struct wt_status *s)
 {
-   status_printf_ln(s, color(WT_STATUS_HEADER, s), );
+   status_printf_ln(s, color(WT_STATUS_HEADER, s), NULL);
 }
 
 #define quote_path quote_path_relative
@@ -794,7 +794,7 @@ static void wt_status_print_other(struct wt_status *s,
string_list_clear(output, 0);
strbuf_release(buf);
 conclude:
-   status_printf_ln(s, GIT_COLOR_NORMAL, );
+   status_printf_ln(s, GIT_COLOR_NORMAL, NULL);
 }
 
 void wt_status_truncate_message_at_cut_line(struct strbuf *buf)
@@ -1292,7 +1292,7 @@ void wt_status_print(struct wt_status *s)
on_what = _(Not currently on any branch.);
}
}
-   status_printf(s, color(WT_STATUS_HEADER, s), );
+   status_printf(s, color(WT_STATUS_HEADER, s), NULL);
status_printf_more(s, branch_status_color, %s, on_what);
status_printf_more(s, branch_color, %s\n, branch_name);
if (!s-is_initial)
@@ -1305,9 +1305,9 @@ void wt_status_print(struct wt_status *s)
free(state.detached_from);
 
if (s-is_initial) {
-   status_printf_ln(s, color(WT_STATUS_HEADER, s), );
+   status_printf_ln(s, color(WT_STATUS_HEADER, s), NULL);
status_printf_ln(s, color(WT_STATUS_HEADER, s), _(Initial 
commit));
-   status_printf_ln(s, color(WT_STATUS_HEADER, s), );
+   status_printf_ln(s, color(WT_STATUS_HEADER, s), NULL);
}
 
wt_status_print_updated(s);
@@ -1324,7 +1324,7 @@ void wt_status_print(struct wt_status *s)
if (s-show_ignored_files)
wt_status_print_other(s, s-ignored, _(Ignored 
files), add -f);
if (advice_status_u_option  2000  s-untracked_in_ms) {
-   status_printf_ln(s, GIT_COLOR_NORMAL, );
+   status_printf_ln(s, GIT_COLOR_NORMAL, NULL);
status_printf_ln(s, GIT_COLOR_NORMAL,
 _(It took %.2f seconds to enumerate 
untracked files. 'status -uno'\n
   may speed it up, but you have to be 
careful not to forget to add\n
-- 
1.9.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/RFC] Documentation: Say that submodule clones use a separate gitdirs.

2014-03-10 Thread Junio C Hamano
Henri GEIST geist.he...@laposte.net writes:

 Le lundi 10 mars 2014 à 08:31 -0700, Junio C Hamano a écrit :
 ...
 This is not limited to submodules.  There are multiple lower-level
 mechanisms for a $path/.git to borrow the repository data from
 elsewhere outside of $path and a cloned submodule uses only one of
 them.  For any such $path, cp -R $path $otherplace will result in
 an $otherplace that does not work as a Git repository in exactly
 the same way, whether it happens to be a submodule checkout or not.
 
 That is why I suggested to enhance description on a more general
 part of the documentation that covers what a Git repository is.
 ...
 If there is some other situation where this can occur as a side effect
 of a git command it can be good to have the user aware of the list or
 at least inform them in general case a git repository cannot be copied
 in a place every body will see.
 Or place a note in the manpage of every git command which can have this
 side effect.

I think we should do two things:

 - In the repository format document, state that there are two
   lower-level mechanisms and a half that lets a repository borrow
   from somewhere else, and cp -R of the former will not result in
   a complete, usable repository, and who employs these mechanisms.

   * Redirecting the entire .git via the textual gitfile mechanism,
 which is used by clone --separate-git-dir and submodule;

   * Borrowing .git/objects read-only from elsewhere, overlaying our
 own, via .git/objects/info/alternates, which is used by clone
 --reference;

   * Redirecting some paths in .git to another, via git workdir;
 soon to be replaced with .git/commondir mechansim.

 - In each of the documentation page on an end-user facing command
   that will be mentioned above, add See also reference to the
   above description in the repository format document.

   We could elaborate the See also as something like If you use
   this feature, do not think you can cp -R the repository to
   elsewhere and expect the copy to function; see also ..., if we
   wanted to.






--
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: [RFC/WIP] Pluggable reference backends

2014-03-10 Thread Jeff King
On Mon, Mar 10, 2014 at 05:14:02PM +0100, David Kastrup wrote:

 [storing refs in sqlite]

 Of course, the basic premise for this feature is let's assume that our
 file and/or operating system suck at providing file system functionality
 at file name granularity.  There have been two historically approaches
 to that problem that are not independent: a) use Linux b) kick Linus.

You didn't define suck here, but there are a number of issues with the
current ref storage system. Here is a sampling:

  1. The filesystem does not present an atomic view of the data (e.g.,
 you read a, then while you are reading b, somebody else updates
 a; your view is one that never existed at any point in time).

  2. Using the filesystem creates D/F conflicts between branches foo
 and foo/bar. Because this name is a primary key even for the
 reflogs, we cannot easily persist reflogs after the ref is removed.

  3. We use packed-refs in conjunction with loose ones to achieve
 reasonable performance when there are a large number of refs. The
 scheme for determining the current value of a ref is complicated
 and error-prone (we had several race conditions that caused real
 data loss).

Those things can be solved through better support from the filesystem.
But they were also solved decades ago by relational databases.

I generally avoid databases where possible. They lock your data up in a
binary format that you can't easily touch with standard unix tools. And
they introduce complexity and opportunity for bugs.

But they are also a proven technology for solving exactly the sorts of
problems that some people are having with git. I do not see a reason not
to consider them as an option for a pluggable refs system. But I also do
not see a reason to inflict their costs on people who do not have those
problems. And that is why Michael's email is about _pluggable_ ref
backends, and not let's convert git to sqlite.

I do not even know if sqlite is going to end up as an interesting
option. But it will be nice to be able to experiment with it easily due
to git's ref code becoming more modular.

-Peff
--
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] rebase: new option to post edit a squashed or fixed up commit

2014-03-10 Thread Junio C Hamano
Nguyễn Thái Ngọc Duy  pclo...@gmail.com writes:

 After squashing or fixing up, you may want to have a final look at the
 commit, edit some more if needed or even do some testing. --postedit
 enables that. This is (to me) a paranoid mode so either I enable it
 for all squashes and fixups, or none. Hence a new option, not new todo
 commands that give finer selection.

If we were to adopt Michael's (?) idea of allowing flags to each
insn in the insn sheet, would this restriction be easily lifted?

That is, instead of saying squash, you say squash --stop or
something.

 diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
 index a1adae8..42061fc 100644
 --- a/git-rebase--interactive.sh
 +++ b/git-rebase--interactive.sh
 @@ -571,6 +571,11 @@ do_next () {
   ;;
   esac
   record_in_rewritten $sha1
 + if test -n $postedit
 + then
 + warn Stopped at $sha1... $rest
 + exit_with_patch $sha1 0
 + fi
   ;;

I would have expected that any new code would stop only at the last
squash (or fixup) in a series of squashes, but this appears to stop
even at an intermediate squashed result, which will not appear in
the final history.  Am I misreading the patch (or misunderstanding
the intent of the patch)?
--
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/2] fix status_printf_ln calls zero-length format warnings

2014-03-10 Thread Jeff King
On Mon, Mar 10, 2014 at 08:27:25PM +0100, Benoit Pierre wrote:

 Those happens with gcc -Wformat-zero-length. Since passing NULL does not
 generate a warning (as __attribute__((printf())) does not imply nonull), 
 modify
 status_printf/status_printf_ln to allow a NULL format and update calls with an
 empty string.

Most of us who compile with -Wall decided a while ago to use
-Wno-format-zero-length, because it really is a silly complaint (it
assumes there are no side effects of the function besides printing the
format string, which is obviously not true in this case).

It would be nice to compile out of the box with -Wall -Werror, and I
think your solution looks relatively clean. But I am slightly concerned
about the assumption that it is OK to pass a NULL fmt parameter to a
function marked with __attribute__((format)).  It certainly seems to be
the case now, and I do not know of any plans for that to change, but it
seems like a potentially obvious thing for the compiler to check.

I dunno; perhaps it has already been considered and rejected by gcc
folks to allow the exact escape hatch we are using here.

-Peff
--
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] rev-parse --parseopt: option argument name hints

2014-03-10 Thread Junio C Hamano
Ilya Bobyr ilya.bo...@gmail.com writes:

 On 3/4/2014 11:22 AM, Junio C Hamano wrote:
 Ilya Bobyr ilya.bo...@gmail.com writes:
 @@ -333,6 +339,7 @@ h,helpshow the help
 foo   some nifty option --foo
   bar=  some cool option --bar with an argument
 +baz=arg   another cool option --baz with an argument named arg
 It probably is better not to have  named arg at the end here, as
 that gives an apparent-but-false contradiction with the Angle
 brackets are added *automatically* and confuse readers.  At least,
 it confused _this_ reader.

 I am not sure I understand what is confusing here.  But I removed the
  named arg part.

After reading Angle brackets are automatically given, seeing that
the argument description has manually spelled arg gave me Huh?.

Without  named arg there is no such confusion.

 If there would be an example, I think, it is easy to understand how it
 works.

Of course.  That is why I suggested to do without  named arg
part---I didn't mean to suggest not to add the example.  I also
think that you can demonstrate something other than '=' (whose usage
is already shown with bar= above) here as well, but I think we can
go either way.

 After the eval in the existing example to parse the $@ argument
 list in this part of the documentation, it may be a good idea to say
 something like:

  The above command, when $@ is --help, produces the
  following help output:

  ... sample output here ...

 to show the actual output.  That way, we can illustrate how input
 baz?arg description of baz is turned into --baz[=arg] output
 clearly (yes, I am suggesting to use '?' in the new example, not '='
 whose usage is already shown in the existing example).

 Documentation on the whole argument parsing is quite short, so, I
 though, adding an example just to show how usage is generated would
 look like I am trying to make this feature look important than it is
 :)

You already are by saying the Angle brackets are automatic, aren't
you?

 At the same time the target structure that holds the option
 description calls this string argh.

OK, that is fine, then (I'd prefer a field name not to sound like
arrrgh, but that is an entirely different topic).

 I've renamed it to end.  It is used to remember possible end of the
 argument name in just one paragraph of code.

Sounds good.
--
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: [RFC/WIP] Pluggable reference backends

2014-03-10 Thread David Kastrup
Jeff King p...@peff.net writes:

 On Mon, Mar 10, 2014 at 05:14:02PM +0100, David Kastrup wrote:

 [storing refs in sqlite]

 Of course, the basic premise for this feature is let's assume that our
 file and/or operating system suck at providing file system functionality
 at file name granularity.  There have been two historically approaches
 to that problem that are not independent: a) use Linux b) kick Linus.

 You didn't define suck here, but there are a number of issues with the
 current ref storage system. Here is a sampling:

   1. The filesystem does not present an atomic view of the data (e.g.,
  you read a, then while you are reading b, somebody else updates
  a; your view is one that never existed at any point in time).

If there are no system calls suitable for addressing this problem that
fundamentally concerns the use of the file system as a file-name
addressed data store, I don't see why kick Linus would not apply here.

   2. Using the filesystem creates D/F conflicts between branches foo
  and foo/bar. Because this name is a primary key even for the
  reflogs, we cannot easily persist reflogs after the ref is
  removed.

That actually sounds more like kick Junio territory (the wonderful
times when kick Linus could achieve almost anything are over).  To
wit: this sounds like a design shortcoming in Git's use of filesystems,
not something that is actually inherent in the use of files.

   3. We use packed-refs in conjunction with loose ones to achieve
  reasonable performance when there are a large number of refs. The
  scheme for determining the current value of a ref is complicated
  and error-prone (we had several race conditions that caused real
  data loss).

Again, that sounds like we are talking about a scenario that is not a
problem of files inherently but rather of Git's ways of managing them.

 Those things can be solved through better support from the filesystem.
 But they were also solved decades ago by relational databases.

Relational databases that are not implemented on raw storage managed by
database servers will still map their operations to file operations.

 But they are also a proven technology for solving exactly the sorts of
 problems that some people are having with git. I do not see a reason
 not to consider them as an option for a pluggable refs system.

But I think it would be wrong to try solving 2. above at the database
level when its actual problem lies with the reference-filename mapping
scheme.

-- 
David Kastrup
--
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 (Mar 2014, #01; Tue, 4)

2014-03-10 Thread Junio C Hamano
Johannes Sixt j.s...@viscovery.net writes:

 Am 3/5/2014 1:10, schrieb Junio C Hamano:
 * nd/gitignore-trailing-whitespace (2014-02-10) 2 commits
  - dir: ignore trailing spaces in exclude patterns
  - dir: warn about trailing spaces in exclude patterns
 
  Warn and then ignore trailing whitespaces in .gitignore files,
  unless they are quoted for fnmatch(3), e.g. path\ .
 
  Will merge to 'next'.

 The new test does not pass on Windows.

Thanks, will mark not to merge to 'master' yet.


--
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] clean: respect pathspecs with -d

2014-03-10 Thread Simon Ruderich
On Mon, Mar 10, 2014 at 01:22:15PM -0400, Jeff King wrote:
 +test_expect_success 'git clean -d respects pathspecs' '
 + mkdir foo 
 + mkdir foobar 
 + git clean -df foobar 
 + test_path_is_dir foo 
 + test_path_is_missing foobar
 +'
 +
  test_done

I think we should also test removing foo, which was also in the
original report, to make sure we don't match prefixes, e.g.:

test_expect_success 'git clean -d respects pathspecs' '
mkdir foo 
mkdir foobar 
git clean -df foo 
test_path_is_missing foo 
test_path_is_dir foobar
'

Regards
Simon
-- 
+ privacy is necessary
+ using gnupg http://gnupg.org
+ public key id: 0x92FEFDB7E44C32F9
--
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 4/7] commit: fix patch hunk editing with commit -p -m

2014-03-10 Thread Jeff King
On Mon, Mar 10, 2014 at 07:49:34PM +0100, Benoit Pierre wrote:

 Don't change git environment: move the GIT_EDITOR=: override to the
 hook command subprocess, like it's already done for GIT_INDEX_FILE.
 
 Signed-off-by: Benoit Pierre benoit.pie...@gmail.com
 ---
  builtin/checkout.c|  8 +++
  builtin/clone.c   |  4 ++--
  builtin/commit.c  | 35 ---
  builtin/gc.c  |  2 +-
  builtin/merge.c   |  6 +++---
  commit.h  |  3 +++
  run-command.c | 44 
 ---
  run-command.h |  6 +-
  t/t7513-commit_-p_-m_hunk_edit.sh |  2 +-
  9 files changed, 79 insertions(+), 31 deletions(-)

This is a lot of change, and in some ways I think it is making things
better overall. However, the simplest fix for this is basically to move
the setting of GIT_EDITOR down to after we prepare the index.

Jun Hao (cc'd) has been preparing a series for this based on the
Bloomberg git hackday a few weeks ago, but it hasn't been sent to the
list yet.

Commits are here:

  https://github.com/bloomberg/git/compare/commit-patch-allow-hunk-editing

if you care to look. I'm not sure which solution is technically
superior, but it's worth considering both.

I regret not encouraging Jun to post to the list sooner, as we might
have avoided some duplicated effort. But that's a sunk cost, and we
should pick up whichever is the best for the project.

-Peff
--
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


  1   2   >