Git development
 help / color / mirror / Atom feed
* [PATCH] [TRIVIAL] Documentation: add: <filepattern>... is optional
From: Paul Bolle @ 2009-08-11 13:03 UTC (permalink / raw)
  To: Junio C Hamano, git

<filepattern>... is optional (e.g. when the --all or --update
options are used) so use square brackets in the synopsis.

Signed-off-by: Paul Bolle <pebolle@tiscali.nl>
---
 Documentation/git-add.txt |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/Documentation/git-add.txt b/Documentation/git-add.txt
index ab1943c..e67b7e8 100644
--- a/Documentation/git-add.txt
+++ b/Documentation/git-add.txt
@@ -10,7 +10,7 @@ SYNOPSIS
 [verse]
 'git add' [-n] [-v] [--force | -f] [--interactive | -i] [--patch | -p]
 	  [--edit | -e] [--all | [--update | -u]] [--intent-to-add | -N]
-	  [--refresh] [--ignore-errors] [--] <filepattern>...
+	  [--refresh] [--ignore-errors] [--] [<filepattern>...]
 
 DESCRIPTION
 -----------
-- 
1.6.4

^ permalink raw reply related

* [JGIT PATCH] Silence noise from javadoc when generating.
From: Robin Rosenberg @ 2009-08-11  5:39 UTC (permalink / raw)
  To: spearce; +Cc: git, Robin Rosenberg

We do not need javadoc(1) to tell us about every file it is processing. With
the -quiet flag we get to see warnings and errors instead.

Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
---
 make_jgit.sh |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/make_jgit.sh b/make_jgit.sh
index 9608b70..e3f7ffa 100755
--- a/make_jgit.sh
+++ b/make_jgit.sh
@@ -122,7 +122,7 @@ echo "Created $O_CLI." || die "Build failed."
 
 echo "Building Javadocs ..."
 for p in $PLUGINS; do
-	javadoc -sourcepath "$p/src/" -d "docs/$p/" \
+	javadoc -quiet -sourcepath "$p/src/" -d "docs/$p/" \
 	`find "$p/src" -name "*.java"`
 done
 
-- 
1.6.3.2.199.g7340d

^ permalink raw reply related

* rename/copy detection not working for git-log?
From: Kevin Green @ 2009-08-11 13:21 UTC (permalink / raw)
  To: git


Hi,

I'm pretty sure I've seen this working as expected at some point in the
past, but I'm now not able to get the full history of a file that's
been moved to another directory and I can't understand why.  Here's a
simple way to reproduce:

  $ git init
  Initialized empty Git repository in /var/tmp/git/.git/
  $ mkdir bin
  $ cat > bin/test.sh
  #!/bin/sh

  echo Hello, world!
  $ git add .
  $ git commit -m 'initial import'
  [master (root-commit) b9dc5be] initial import
   1 files changed, 3 insertions(+), 0 deletions(-)
    create mode 100644 bin/test.sh
  $ mkdir scripts
  $ git mv bin/test.sh scripts/test.sh
  $ git commit -m 'move bin/ to scripts/'
  [master b4c6c72] move bin/ to scripts/
   1 files changed, 0 insertions(+), 0 deletions(-)
    rename {bin => scripts}/test.sh (100%)
  $ echo 'echo Goodbye!' >> scripts/test.sh
  $ git commit -a -m 'make a change in scripts/'
  [master 59830d5] make a change in scripts/
   1 files changed, 1 insertions(+), 0 deletions(-)


This now has full history of:

  $ git log --pretty=oneline
  59830d59f6b4d48b28f2ae8d51e921a9c8842b06 make a change in scripts/
  b4c6c72c548a1c17550c01350beede235d481aa4 move bin/ to scripts/
  b9dc5be440d2c843554e9b0302435d9a6f78cd65 initial import 

and the history of scripts/test.sh is as I expect:

  $ git log --pretty=oneline -- scripts/test.sh
  59830d59f6b4d48b28f2ae8d51e921a9c8842b06 make a change in scripts/
  b4c6c72c548a1c17550c01350beede235d481aa4 move bin/ to scripts/

and the history of bin/test.sh is as I would expect:

  $ git log --pretty=oneline -- bin/test.sh
  b4c6c72c548a1c17550c01350beede235d481aa4 move bin/ to scripts/
  b9dc5be440d2c843554e9b0302435d9a6f78cd65 initial import


But, I would expect that some combination of -M and -C would find me
the full history of the current test.sh script so I could see what
happened to it before it was moved.  (Okay, the example above is not so
interesting, but in the real world, bin/test.sh would have had lots of
commits before moving):

  $ git log --pretty=oneline -M -C -C -- scripts/test.sh
  59830d59f6b4d48b28f2ae8d51e921a9c8842b06 make a change in scripts/
  b4c6c72c548a1c17550c01350beede235d481aa4 move bin/ to scripts/

git-blame seems to get this right:

  $ git blame scripts/test.sh
  ^b9dc5be bin/test.sh     (Kevin Green 2009-08-11 09:07:06 -0400 1) #!/bin/sh
  ^b9dc5be bin/test.sh     (Kevin Green 2009-08-11 09:07:06 -0400 2)
  ^b9dc5be bin/test.sh     (Kevin Green 2009-08-11 09:07:06 -0400 3) echo Hello, world!
  59830d59 scripts/test.sh (Kevin Green 2009-08-11 09:08:29 -0400 4) echo Goodbye!


What am I missing?


Thanks

--Kevin

^ permalink raw reply

* Re: rename/copy detection not working for git-log?
From: Bruce Stephens @ 2009-08-11 13:42 UTC (permalink / raw)
  To: git
In-Reply-To: <20090811132144.GJ6327@morganstanley.com>

Kevin Green <Kevin.T.Green@morganstanley.com> writes:

[...]

> What am I missing?

I'd guess --follow

^ permalink raw reply

* Re: Unable to checkout a branch after cloning
From: Michael J Gruber @ 2009-08-11 13:55 UTC (permalink / raw)
  To: Matthew Lear; +Cc: git
In-Reply-To: <4A81613F.2080309@bubblegen.co.uk>

Matthew Lear venit, vidit, dixit 11.08.2009 14:17:
> Hi Michael - thanks for your reply.
> Michael J Gruber wrote:
>> Matthew Lear venit, vidit, dixit 11.08.2009 12:10:
>>> Hi all,
>>>
>>> Apologies for perhaps a silly question, but I'd very much appreciate a
>>> little bit of assistance.
>>>
>>> I've set up a git repository on a machine accessible from the internet
>>> with the intention to share code with another developer. We clone the
>>> repository, commit changes then push back as you'd expect. The server
>>> runs gitweb for repository browsing. Clients are running git v1.6.0.6.
>>>
>>> When I created the initial repository I also created two additional
>>> branches - 'upstream' and 'custom'. The former is to act as a 'vendor
>>> branch' and the latter contains code specific to the custom platform
>>> that we're working on. The master branch contains merges from the
>>> upstream branch and also changes that we've made. The custom branch
>>> contains merges from master with custom platform specific changes.
>>>
>>> I've committed changes and on both upstream and custom branches as work
>>> progressed, merged them where appropriate, added tags etc and pushed
>>> everything to the remote repository. No problem. I can view the
>>> branches, tags etc in gitweb and everything looks fine.
>>>
>>> However, I can clone a new repository just fine but I'm unable to
>>> checkout the upstream or custom branches. After cloning, only the master
>>> branch is available, ie:
>>>
>>>> git checkout upstream
>>> error: pathspec 'upstream' did not match any file(s) known to git.
>>>
>>>> git branch -a
>>> * master
>>>   origin/HEAD
>>>   origin/master
>>>
>>> .git/config:
>>>
>>> [core]
>>>         repositoryformatversion = 0
>>>         filemode = true
>>>         bare = false
>>>         logallrefupdates = true
>>> [remote "origin"]
>>>         url = https://mysite/git/project.git
>>>         fetch = +refs/heads/*:refs/remotes/origin/*
>>> [branch "master"]
>>>         remote = origin
>>>         merge = refs/heads/master
>>>
>>> But the initial local repository where I work (ie created the branches,
>>> committed changes, tag, push etc) seems to be fine, ie
>>>
>>>> git checkout upstream
>>> Switched to branch "upstream"
>>>
>>>> git branch -a
>>>   custom
>>> * master
>>>   upstream
>>>
>>> .git/config:
>>>
>>> [core]
>>>         repositoryformatversion = 0
>>>         filemode = true
>>>         bare = false
>>>         logallrefupdates = true
>>> [remote "origin"]
>>>         url = https://mysite/git/project.git
>>>         fetch = +refs/heads/*:refs/remotes/origin/*
>>>
>>>
>>> Developers need to be able to clone the repository and then switch to
>>> the appropriate branch in order to work. However it seems that after a
>>> clone, only the master branch is available.
>>>
>>> Why is this?
>>>
>>> Any help would be much appreciated indeed.
>>
>> If I understand you correctly you have 3 repos: the "initial" one on
>> which everything is as expected, the "server" one and the "new clone"
>> which is missing branches.
> 
> Yes, that's correct.
> 
>> Now: How's the server one doing, i.e. what does "git ls-remote
>> https://mysite/git/project.git" say? I suspect that one either does not
>> have the branches (you haven't told us how you pushed) or in the wrong
>> place (remotes/).
> 
>> git ls-remote https://mysite/git/project.git
> 065f5f13d5f8e786729db1623cc53767c963e959        HEAD
> 065f5f13d5f8e786729db1623cc53767c963e959        refs/heads/master
> 
> Hmm. So it seems that the branches are not actually on the server
> repository. So how come I can see them with gitweb..?
> 
> I've been pushing from the 'initial' repository with git push --all and
> git push --tags.
> 
> However, when I try a git push from the initial repository I get the
> following:
> 
>> git push --all
> Fetching remote heads...
>   refs/
>   refs/heads/
>   refs/tags/
> 'refs/heads/custom': up-to-date
> 'refs/heads/master': up-to-date
> 'refs/heads/upstream': up-to-date
> 
> -- Matt

Does the situation improve if, on the server, you run git
update-server-info? Do you have a post-update hook there?

Michael

^ permalink raw reply

* [PATCH] git stash: Give friendlier errors when there is nothing to apply
From: Ori Avtalion @ 2009-08-11 11:12 UTC (permalink / raw)
  To: git
In-Reply-To: <200908111409.04506.trast@student.ethz.ch>

The change makes sure a stash (given or default) exists before
checking if the working tree is dirty.

If the default stash is requested, the old message was scary and
included a 'fatal' error from rev-parse:
     fatal: Needed a single revision
     : no valid stashed state found

It is replaced with a friendlier 'Nothing to apply' error, similar to
'git stash branch'.

If a specific stash is specified, the 'Needed a single revision' errors
from rev-parse are suppressed.

Signed-off-by: Ori Avtalion <ori@avtalion.name>
---

Thomas, I added handling for the 'git stash apply <stash>' case based
on your reminder, and also changed the error messages related to it.

All of the stash tests pass, as before.

 git-stash.sh |   27 ++++++++++++++++-----------
 1 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/git-stash.sh b/git-stash.sh
index 03e589f..d61c9d0 100755
--- a/git-stash.sh
+++ b/git-stash.sh
@@ -162,10 +162,6 @@ show_stash () {
 }
 
 apply_stash () {
-	git update-index -q --refresh &&
-	git diff-files --quiet --ignore-submodules ||
-		die 'Cannot apply to a dirty working tree, please stage your changes'
-
 	unstash_index=
 
 	while test $# != 0
@@ -184,18 +180,27 @@ apply_stash () {
 		shift
 	done
 
-	# current index state
-	c_tree=$(git write-tree) ||
-		die 'Cannot apply a stash in the middle of a merge'
+	if test $# = 0
+	then
+		have_stash || die 'Nothing to apply'
+	fi
 
 	# stash records the work tree, and is a merge between the
 	# base commit (first parent) and the index tree (second parent).
-	s=$(git rev-parse --verify --default $ref_stash "$@") &&
-	w_tree=$(git rev-parse --verify "$s:") &&
-	b_tree=$(git rev-parse --verify "$s^1:") &&
-	i_tree=$(git rev-parse --verify "$s^2:") ||
+	s=$(git rev-parse --quiet --verify --default $ref_stash "$@") &&
+	w_tree=$(git rev-parse --quiet --verify "$s:") &&
+	b_tree=$(git rev-parse --quiet --verify "$s^1:") &&
+	i_tree=$(git rev-parse --quiet --verify "$s^2:") ||
 		die "$*: no valid stashed state found"
 
+	git update-index -q --refresh &&
+	git diff-files --quiet --ignore-submodules ||
+		die 'Cannot apply to a dirty working tree, please stage your changes'
+
+	# current index state
+	c_tree=$(git write-tree) ||
+		die 'Cannot apply a stash in the middle of a merge'
+
 	unstashed_index_tree=
 	if test -n "$unstash_index" && test "$b_tree" != "$i_tree" &&
 			test "$c_tree" != "$i_tree"
-- 
1.6.4.115.g82cf7

^ permalink raw reply related

* Re: rename/copy detection not working for git-log?
From: Kevin Green @ 2009-08-11 13:57 UTC (permalink / raw)
  To: Bruce Stephens; +Cc: git@vger.kernel.org
In-Reply-To: <807hxasbz4.fsf@tiny.isode.net>

On 08/11/09 09:42:55, Bruce Stephens wrote:
> Kevin Green <Kevin.T.Green@morganstanley.com> writes:
> 
> [...]
> 
> > What am I missing?
> 
> I'd guess --follow

Ah, yep...  didn't see that earlier.  Exactly what I need, thanks.


--Kevin

^ permalink raw reply

* [JGIT PATCH] Improve error handling for writing FETCH_HEAD
From: Robin Rosenberg @ 2009-08-11  5:48 UTC (permalink / raw)
  To: spearce; +Cc: git, Robin Rosenberg

PrintWriter hides error handling from us and we want it. We
also want \n as line terminator so Writer is just as simple. Try-
finally blocks added for cleanup on failure.

Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
---
 .../spearce/jgit/transport/FetchHeadRecord.java    |   25 +++++++++---------
 .../org/spearce/jgit/transport/FetchProcess.java   |   27 ++++++++++---------
 2 files changed, 27 insertions(+), 25 deletions(-)

diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/FetchHeadRecord.java b/org.spearce.jgit/src/org/spearce/jgit/transport/FetchHeadRecord.java
index d957028..62ec38a 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/FetchHeadRecord.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/FetchHeadRecord.java
@@ -41,7 +41,8 @@
 import static org.spearce.jgit.lib.Constants.R_REMOTES;
 import static org.spearce.jgit.lib.Constants.R_TAGS;
 
-import java.io.PrintWriter;
+import java.io.IOException;
+import java.io.Writer;
 
 import org.spearce.jgit.lib.ObjectId;
 
@@ -54,7 +55,7 @@
 
 	URIish sourceURI;
 
-	void write(final PrintWriter pw) {
+	void write(final Writer pw) throws IOException {
 		final String type;
 		final String name;
 		if (sourceName.startsWith(R_HEADS)) {
@@ -71,16 +72,16 @@ void write(final PrintWriter pw) {
 			name = sourceName;
 		}
 
-		pw.print(newValue.name());
-		pw.print('\t');
+		pw.write(newValue.name());
+		pw.write('\t');
 		if (notForMerge)
-			pw.print("not-for-merge");
-		pw.print('\t');
-		pw.print(type);
-		pw.print(" '");
-		pw.print(name);
-		pw.print("' of ");
-		pw.print(sourceURI);
-		pw.println();
+			pw.write("not-for-merge");
+		pw.write('\t');
+		pw.write(type);
+		pw.write(" '");
+		pw.write(name);
+		pw.write("' of ");
+		pw.write(sourceURI.toString());
+		pw.write("\n");
 	}
 }
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/FetchProcess.java b/org.spearce.jgit/src/org/spearce/jgit/transport/FetchProcess.java
index 08d7d65..c899c8c 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/FetchProcess.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/FetchProcess.java
@@ -41,7 +41,7 @@
 import java.io.File;
 import java.io.IOException;
 import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
+import java.io.Writer;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -264,20 +264,21 @@ private void removeFetchHeadRecord(final ObjectId want) {
 	private void updateFETCH_HEAD(final FetchResult result) throws IOException {
 		final LockFile lock = new LockFile(new File(transport.local
 				.getDirectory(), "FETCH_HEAD"));
-		if (lock.lock()) {
-			final PrintWriter pw = new PrintWriter(new OutputStreamWriter(lock
-					.getOutputStream())) {
-				@Override
-				public void println() {
-					print('\n');
+		try {
+			if (lock.lock()) {
+				final Writer w = new OutputStreamWriter(lock.getOutputStream());
+				try {
+					for (final FetchHeadRecord h : fetchHeadUpdates) {
+						h.write(w);
+						result.add(h);
+					}
+				} finally {
+					w.close();
 				}
-			};
-			for (final FetchHeadRecord h : fetchHeadUpdates) {
-				h.write(pw);
-				result.add(h);
+				lock.commit();
 			}
-			pw.close();
-			lock.commit();
+		} finally {
+			lock.unlock();
 		}
 	}
 
-- 
1.6.3.2.199.g7340d

^ permalink raw reply related

* Re: Unable to checkout a branch after cloning
From: Matthew Lear @ 2009-08-11 14:24 UTC (permalink / raw)
  To: Michael J Gruber; +Cc: git
In-Reply-To: <4A817840.9000405@drmicha.warpmail.net>

Michael J Gruber wrote:
> Matthew Lear venit, vidit, dixit 11.08.2009 14:17:
>> Hi Michael - thanks for your reply.
>> Michael J Gruber wrote:
>>> Matthew Lear venit, vidit, dixit 11.08.2009 12:10:
>>>> Hi all,
>>>>
>>>> Apologies for perhaps a silly question, but I'd very much appreciate a
>>>> little bit of assistance.
>>>>
>>>> I've set up a git repository on a machine accessible from the internet
>>>> with the intention to share code with another developer. We clone the
>>>> repository, commit changes then push back as you'd expect. The server
>>>> runs gitweb for repository browsing. Clients are running git v1.6.0.6.
>>>>
>>>> When I created the initial repository I also created two additional
>>>> branches - 'upstream' and 'custom'. The former is to act as a 'vendor
>>>> branch' and the latter contains code specific to the custom platform
>>>> that we're working on. The master branch contains merges from the
>>>> upstream branch and also changes that we've made. The custom branch
>>>> contains merges from master with custom platform specific changes.
>>>>
>>>> I've committed changes and on both upstream and custom branches as work
>>>> progressed, merged them where appropriate, added tags etc and pushed
>>>> everything to the remote repository. No problem. I can view the
>>>> branches, tags etc in gitweb and everything looks fine.
>>>>
>>>> However, I can clone a new repository just fine but I'm unable to
>>>> checkout the upstream or custom branches. After cloning, only the master
>>>> branch is available, ie:
>>>>
>>>>> git checkout upstream
>>>> error: pathspec 'upstream' did not match any file(s) known to git.
>>>>
>>>>> git branch -a
>>>> * master
>>>>   origin/HEAD
>>>>   origin/master
>>>>
>>>> .git/config:
>>>>
>>>> [core]
>>>>         repositoryformatversion = 0
>>>>         filemode = true
>>>>         bare = false
>>>>         logallrefupdates = true
>>>> [remote "origin"]
>>>>         url = https://mysite/git/project.git
>>>>         fetch = +refs/heads/*:refs/remotes/origin/*
>>>> [branch "master"]
>>>>         remote = origin
>>>>         merge = refs/heads/master
>>>>
>>>> But the initial local repository where I work (ie created the branches,
>>>> committed changes, tag, push etc) seems to be fine, ie
>>>>
>>>>> git checkout upstream
>>>> Switched to branch "upstream"
>>>>
>>>>> git branch -a
>>>>   custom
>>>> * master
>>>>   upstream
>>>>
>>>> .git/config:
>>>>
>>>> [core]
>>>>         repositoryformatversion = 0
>>>>         filemode = true
>>>>         bare = false
>>>>         logallrefupdates = true
>>>> [remote "origin"]
>>>>         url = https://mysite/git/project.git
>>>>         fetch = +refs/heads/*:refs/remotes/origin/*
>>>>
>>>>
>>>> Developers need to be able to clone the repository and then switch to
>>>> the appropriate branch in order to work. However it seems that after a
>>>> clone, only the master branch is available.
>>>>
>>>> Why is this?
>>>>
>>>> Any help would be much appreciated indeed.
>>> If I understand you correctly you have 3 repos: the "initial" one on
>>> which everything is as expected, the "server" one and the "new clone"
>>> which is missing branches.
>> Yes, that's correct.
>>
>>> Now: How's the server one doing, i.e. what does "git ls-remote
>>> https://mysite/git/project.git" say? I suspect that one either does not
>>> have the branches (you haven't told us how you pushed) or in the wrong
>>> place (remotes/).
>>> git ls-remote https://mysite/git/project.git
>> 065f5f13d5f8e786729db1623cc53767c963e959        HEAD
>> 065f5f13d5f8e786729db1623cc53767c963e959        refs/heads/master
>>
>> Hmm. So it seems that the branches are not actually on the server
>> repository. So how come I can see them with gitweb..?
>>
>> I've been pushing from the 'initial' repository with git push --all and
>> git push --tags.
>>
>> However, when I try a git push from the initial repository I get the
>> following:
>>
>>> git push --all
>> Fetching remote heads...
>>   refs/
>>   refs/heads/
>>   refs/tags/
>> 'refs/heads/custom': up-to-date
>> 'refs/heads/master': up-to-date
>> 'refs/heads/upstream': up-to-date
>>
>> -- Matt
> 
> Does the situation improve if, on the server, you run git
> update-server-info? Do you have a post-update hook there?
> 
> Michael

I ran git update-server-info on the server machine. I read about this
and thought I had made the necessary change to add it as a post commit
hook. I guess not (so will double check). However, something is still
not quite right upon cloning:

> git clone https://mysite/git/project.git
Initialized empty Git repository in /home/matt/git-repos/project/.git/
Checking out files: 100% (26747/26747), done.

> git branch -a
* master
  origin/HEAD
  origin/custom
  origin/master
  origin/upstream

> git checkout upstream
error: pathspec 'upstream' did not match any file(s) known to git.

So it seems that the cloned repository is now aware of the branches
(improvement) but I'm still unable to switch to a branch.

This is probably now a case of me reading the manual but I'd appreciate
your thoughts nonetheless.

Thanks for your continued feedback,
--  Matt

^ permalink raw reply

* Re: Unable to checkout a branch after cloning
From: Michael J Gruber @ 2009-08-11 14:32 UTC (permalink / raw)
  To: Matthew Lear; +Cc: git
In-Reply-To: <4A817F3B.7070308@bubblegen.co.uk>

Matthew Lear venit, vidit, dixit 11.08.2009 16:24:
> Michael J Gruber wrote:
>> Matthew Lear venit, vidit, dixit 11.08.2009 14:17:
>>> Hi Michael - thanks for your reply.
>>> Michael J Gruber wrote:
>>>> Matthew Lear venit, vidit, dixit 11.08.2009 12:10:
>>>>> Hi all,
>>>>>
>>>>> Apologies for perhaps a silly question, but I'd very much appreciate a
>>>>> little bit of assistance.
>>>>>
>>>>> I've set up a git repository on a machine accessible from the internet
>>>>> with the intention to share code with another developer. We clone the
>>>>> repository, commit changes then push back as you'd expect. The server
>>>>> runs gitweb for repository browsing. Clients are running git v1.6.0.6.
>>>>>
>>>>> When I created the initial repository I also created two additional
>>>>> branches - 'upstream' and 'custom'. The former is to act as a 'vendor
>>>>> branch' and the latter contains code specific to the custom platform
>>>>> that we're working on. The master branch contains merges from the
>>>>> upstream branch and also changes that we've made. The custom branch
>>>>> contains merges from master with custom platform specific changes.
>>>>>
>>>>> I've committed changes and on both upstream and custom branches as work
>>>>> progressed, merged them where appropriate, added tags etc and pushed
>>>>> everything to the remote repository. No problem. I can view the
>>>>> branches, tags etc in gitweb and everything looks fine.
>>>>>
>>>>> However, I can clone a new repository just fine but I'm unable to
>>>>> checkout the upstream or custom branches. After cloning, only the master
>>>>> branch is available, ie:
>>>>>
>>>>>> git checkout upstream
>>>>> error: pathspec 'upstream' did not match any file(s) known to git.
>>>>>
>>>>>> git branch -a
>>>>> * master
>>>>>   origin/HEAD
>>>>>   origin/master
>>>>>
>>>>> .git/config:
>>>>>
>>>>> [core]
>>>>>         repositoryformatversion = 0
>>>>>         filemode = true
>>>>>         bare = false
>>>>>         logallrefupdates = true
>>>>> [remote "origin"]
>>>>>         url = https://mysite/git/project.git
>>>>>         fetch = +refs/heads/*:refs/remotes/origin/*
>>>>> [branch "master"]
>>>>>         remote = origin
>>>>>         merge = refs/heads/master
>>>>>
>>>>> But the initial local repository where I work (ie created the branches,
>>>>> committed changes, tag, push etc) seems to be fine, ie
>>>>>
>>>>>> git checkout upstream
>>>>> Switched to branch "upstream"
>>>>>
>>>>>> git branch -a
>>>>>   custom
>>>>> * master
>>>>>   upstream
>>>>>
>>>>> .git/config:
>>>>>
>>>>> [core]
>>>>>         repositoryformatversion = 0
>>>>>         filemode = true
>>>>>         bare = false
>>>>>         logallrefupdates = true
>>>>> [remote "origin"]
>>>>>         url = https://mysite/git/project.git
>>>>>         fetch = +refs/heads/*:refs/remotes/origin/*
>>>>>
>>>>>
>>>>> Developers need to be able to clone the repository and then switch to
>>>>> the appropriate branch in order to work. However it seems that after a
>>>>> clone, only the master branch is available.
>>>>>
>>>>> Why is this?
>>>>>
>>>>> Any help would be much appreciated indeed.
>>>> If I understand you correctly you have 3 repos: the "initial" one on
>>>> which everything is as expected, the "server" one and the "new clone"
>>>> which is missing branches.
>>> Yes, that's correct.
>>>
>>>> Now: How's the server one doing, i.e. what does "git ls-remote
>>>> https://mysite/git/project.git" say? I suspect that one either does not
>>>> have the branches (you haven't told us how you pushed) or in the wrong
>>>> place (remotes/).
>>>> git ls-remote https://mysite/git/project.git
>>> 065f5f13d5f8e786729db1623cc53767c963e959        HEAD
>>> 065f5f13d5f8e786729db1623cc53767c963e959        refs/heads/master
>>>
>>> Hmm. So it seems that the branches are not actually on the server
>>> repository. So how come I can see them with gitweb..?
>>>
>>> I've been pushing from the 'initial' repository with git push --all and
>>> git push --tags.
>>>
>>> However, when I try a git push from the initial repository I get the
>>> following:
>>>
>>>> git push --all
>>> Fetching remote heads...
>>>   refs/
>>>   refs/heads/
>>>   refs/tags/
>>> 'refs/heads/custom': up-to-date
>>> 'refs/heads/master': up-to-date
>>> 'refs/heads/upstream': up-to-date
>>>
>>> -- Matt
>>
>> Does the situation improve if, on the server, you run git
>> update-server-info? Do you have a post-update hook there?
>>
>> Michael
> 
> I ran git update-server-info on the server machine. I read about this
> and thought I had made the necessary change to add it as a post commit
> hook. I guess not (so will double check). However, something is still
> not quite right upon cloning:
> 
>> git clone https://mysite/git/project.git
> Initialized empty Git repository in /home/matt/git-repos/project/.git/
> Checking out files: 100% (26747/26747), done.
> 
>> git branch -a
> * master
>   origin/HEAD
>   origin/custom
>   origin/master
>   origin/upstream

We're making progress, that's good ;)
Re. the hook: Make sure it's executable and the extension .sample is
removed.

(gitweb and http access are two different things, which is a common
source of confusion)

> 
>> git checkout upstream
> error: pathspec 'upstream' did not match any file(s) known to git.
> 
> So it seems that the cloned repository is now aware of the branches
> (improvement) but I'm still unable to switch to a branch.
> 
> This is probably now a case of me reading the manual but I'd appreciate
> your thoughts nonetheless.

Well, there is no branch names upstream. There's only one named
origin/upstream, and it's a remote branch. Meaning: checking it out will
produce a detached head, which may or may not be what you want. If you
want to create a branch to work on upstream, do something like

git checkout -b myupstream origin/upstream

(git does something like git checkout -b master origin/master
automatically when cloning, which I think is a common source of confusion)

> Thanks for your continued feedback,
> --  Matt

Cheers,
Michael

^ permalink raw reply

* [PATCH] Re: [TRIVIAL] Documentation: merge: one <remote> is required
From: Nicolas Sebrecht @ 2009-08-11 14:42 UTC (permalink / raw)
  To: Paul Bolle; +Cc: Junio C Hamano, git
In-Reply-To: <1249995838.1589.3.camel@localhost.localdomain>

The 11/08/09, Paul Bolle wrote:
> merge only requires one <remote>, so "<remote>..." should be used in the
> synopsis (and not "<remote> <remote>...").
> 

<...>

>  'git merge' [-n] [--stat] [--no-commit] [--squash] [-s <strategy>]...
> -	[-m <msg>] <remote> <remote>...
> +	[-m <msg>] <remote>...
>  'git merge' <msg> HEAD <remote>...

Shoudn't be 

   [-m <msg>] <remote> [<remote>...]

or

   [-m <msg>] <remote>[...]

instead?

-- 
Nicolas Sebrecht

^ permalink raw reply

* [PATCH] Re: [TRIVIAL] Documentation: add: <filepattern>... is optional
From: Nicolas Sebrecht @ 2009-08-11 14:50 UTC (permalink / raw)
  To: Paul Bolle; +Cc: Junio C Hamano, git
In-Reply-To: <1249995790.1589.2.camel@localhost.localdomain>

The 11/08/09, Paul Bolle wrote:

> <filepattern>... is optional (e.g. when the --all or --update
> options are used) so use square brackets in the synopsis.

So <filepattern> is needed in all other cases. The '-u' description
already has

	" If no paths are specified, all tracked files in the current
  directory and its subdirectories are updated. "

and '-a' refers to '-u'

  "(same as --update)"

.

-- 
Nicolas Sebrecht

^ permalink raw reply

* Re: Unable to checkout a branch after cloning
From: Matthew Lear @ 2009-08-11 14:54 UTC (permalink / raw)
  To: Michael J Gruber; +Cc: git
In-Reply-To: <4A818119.6000302@drmicha.warpmail.net>

Michael J Gruber wrote:
> Matthew Lear venit, vidit, dixit 11.08.2009 16:24:
>> Michael J Gruber wrote:
>>> Matthew Lear venit, vidit, dixit 11.08.2009 14:17:
>>>> Hi Michael - thanks for your reply.
>>>> Michael J Gruber wrote:
>>>>> Matthew Lear venit, vidit, dixit 11.08.2009 12:10:
>>>>>> Hi all,
>>>>>>
>>>>>> Apologies for perhaps a silly question, but I'd very much appreciate a
>>>>>> little bit of assistance.
>>>>>>
>>>>>> I've set up a git repository on a machine accessible from the internet
>>>>>> with the intention to share code with another developer. We clone the
>>>>>> repository, commit changes then push back as you'd expect. The server
>>>>>> runs gitweb for repository browsing. Clients are running git v1.6.0.6.
>>>>>>
>>>>>> When I created the initial repository I also created two additional
>>>>>> branches - 'upstream' and 'custom'. The former is to act as a 'vendor
>>>>>> branch' and the latter contains code specific to the custom platform
>>>>>> that we're working on. The master branch contains merges from the
>>>>>> upstream branch and also changes that we've made. The custom branch
>>>>>> contains merges from master with custom platform specific changes.
>>>>>>
>>>>>> I've committed changes and on both upstream and custom branches as work
>>>>>> progressed, merged them where appropriate, added tags etc and pushed
>>>>>> everything to the remote repository. No problem. I can view the
>>>>>> branches, tags etc in gitweb and everything looks fine.
>>>>>>
>>>>>> However, I can clone a new repository just fine but I'm unable to
>>>>>> checkout the upstream or custom branches. After cloning, only the master
>>>>>> branch is available, ie:
>>>>>>
>>>>>>> git checkout upstream
>>>>>> error: pathspec 'upstream' did not match any file(s) known to git.
>>>>>>
>>>>>>> git branch -a
>>>>>> * master
>>>>>>   origin/HEAD
>>>>>>   origin/master
>>>>>>
>>>>>> .git/config:
>>>>>>
>>>>>> [core]
>>>>>>         repositoryformatversion = 0
>>>>>>         filemode = true
>>>>>>         bare = false
>>>>>>         logallrefupdates = true
>>>>>> [remote "origin"]
>>>>>>         url = https://mysite/git/project.git
>>>>>>         fetch = +refs/heads/*:refs/remotes/origin/*
>>>>>> [branch "master"]
>>>>>>         remote = origin
>>>>>>         merge = refs/heads/master
>>>>>>
>>>>>> But the initial local repository where I work (ie created the branches,
>>>>>> committed changes, tag, push etc) seems to be fine, ie
>>>>>>
>>>>>>> git checkout upstream
>>>>>> Switched to branch "upstream"
>>>>>>
>>>>>>> git branch -a
>>>>>>   custom
>>>>>> * master
>>>>>>   upstream
>>>>>>
>>>>>> .git/config:
>>>>>>
>>>>>> [core]
>>>>>>         repositoryformatversion = 0
>>>>>>         filemode = true
>>>>>>         bare = false
>>>>>>         logallrefupdates = true
>>>>>> [remote "origin"]
>>>>>>         url = https://mysite/git/project.git
>>>>>>         fetch = +refs/heads/*:refs/remotes/origin/*
>>>>>>
>>>>>>
>>>>>> Developers need to be able to clone the repository and then switch to
>>>>>> the appropriate branch in order to work. However it seems that after a
>>>>>> clone, only the master branch is available.
>>>>>>
>>>>>> Why is this?
>>>>>>
>>>>>> Any help would be much appreciated indeed.
>>>>> If I understand you correctly you have 3 repos: the "initial" one on
>>>>> which everything is as expected, the "server" one and the "new clone"
>>>>> which is missing branches.
>>>> Yes, that's correct.
>>>>
>>>>> Now: How's the server one doing, i.e. what does "git ls-remote
>>>>> https://mysite/git/project.git" say? I suspect that one either does not
>>>>> have the branches (you haven't told us how you pushed) or in the wrong
>>>>> place (remotes/).
>>>>> git ls-remote https://mysite/git/project.git
>>>> 065f5f13d5f8e786729db1623cc53767c963e959        HEAD
>>>> 065f5f13d5f8e786729db1623cc53767c963e959        refs/heads/master
>>>>
>>>> Hmm. So it seems that the branches are not actually on the server
>>>> repository. So how come I can see them with gitweb..?
>>>>
>>>> I've been pushing from the 'initial' repository with git push --all and
>>>> git push --tags.
>>>>
>>>> However, when I try a git push from the initial repository I get the
>>>> following:
>>>>
>>>>> git push --all
>>>> Fetching remote heads...
>>>>   refs/
>>>>   refs/heads/
>>>>   refs/tags/
>>>> 'refs/heads/custom': up-to-date
>>>> 'refs/heads/master': up-to-date
>>>> 'refs/heads/upstream': up-to-date
>>>>
>>>> -- Matt
>>> Does the situation improve if, on the server, you run git
>>> update-server-info? Do you have a post-update hook there?
>>>
>>> Michael
>> I ran git update-server-info on the server machine. I read about this
>> and thought I had made the necessary change to add it as a post commit
>> hook. I guess not (so will double check). However, something is still
>> not quite right upon cloning:
>>
>>> git clone https://mysite/git/project.git
>> Initialized empty Git repository in /home/matt/git-repos/project/.git/
>> Checking out files: 100% (26747/26747), done.
>>
>>> git branch -a
>> * master
>>   origin/HEAD
>>   origin/custom
>>   origin/master
>>   origin/upstream
> 
> We're making progress, that's good ;)
> Re. the hook: Make sure it's executable and the extension .sample is
> removed.
> 
> (gitweb and http access are two different things, which is a common
> source of confusion)
> 
>>> git checkout upstream
>> error: pathspec 'upstream' did not match any file(s) known to git.
>>
>> So it seems that the cloned repository is now aware of the branches
>> (improvement) but I'm still unable to switch to a branch.
>>
>> This is probably now a case of me reading the manual but I'd appreciate
>> your thoughts nonetheless.
> 
> Well, there is no branch names upstream. There's only one named
> origin/upstream, and it's a remote branch. Meaning: checking it out will
> produce a detached head, which may or may not be what you want. If you
> want to create a branch to work on upstream, do something like
> 
> git checkout -b myupstream origin/upstream
> 
> (git does something like git checkout -b master origin/master
> automatically when cloning, which I think is a common source of confusion)

I've fixed the server hook scripts (embarrassingly, they were executable
but still had the .sample suffix - that's really not going to work!).

I've actually just read through the manual about detached heads. This is
not what I want but your solution to create a branch to track the remote
branch is exactly what I need.

Where ever you are in the world, many thanks for your continued help and
assistance. Very much appreciated indeed.

Cheers,
--  Matt

^ permalink raw reply

* Re: [PATCH] Re: [TRIVIAL] Documentation: merge: one <remote> is required
From: Paul Bolle @ 2009-08-11 14:58 UTC (permalink / raw)
  To: Nicolas Sebrecht; +Cc: Junio C Hamano, git
In-Reply-To: <20090811144253.GA12956@vidovic>

On Tue, 2009-08-11 at 16:42 +0200, Nicolas Sebrecht wrote:
> The 11/08/09, Paul Bolle wrote:
> >  'git merge' [-n] [--stat] [--no-commit] [--squash] [-s <strategy>]...
> > -	[-m <msg>] <remote> <remote>...
> > +	[-m <msg>] <remote>...
> >  'git merge' <msg> HEAD <remote>...
> 
> Shoudn't be 
> 
>    [-m <msg>] <remote> [<remote>...]

No, since "<remote>..." means one or more instances of the "<remote>"
option.  

> or
> 
>    [-m <msg>] <remote>[...]

Is "<$something>[...]" used anywhere? It makes little sense to me.

> instead?

Paul Bolle

^ permalink raw reply

* Re: block-sha1: improve code on large-register-set machines
From: Linus Torvalds @ 2009-08-11 15:04 UTC (permalink / raw)
  To: Nicolas Pitre; +Cc: Git Mailing List, Junio C Hamano
In-Reply-To: <alpine.LFD.2.00.0908102246210.10633@xanadu.home>



On Tue, 11 Aug 2009, Nicolas Pitre wrote:
> 
> #define SHA_SRC(t) \
>   ({ unsigned char *__d = (unsigned char *)&data[t]; \
>      (__d[0] << 24) | (__d[1] << 16) | (__d[2] << 8) | (__d[3] << 0); })
> 
> And this provides the exact same performance as the ntohl() based 
> version (4.980s) except that this now cope with unaligned buffers too.

Is it better to do a (conditional) memcpy up front? Or is the byte-based 
one better just because you always end up doing the shifting anyway due to 
most ARM situations being little-endian?

I _suspect_ that most large SHA1 calls from git are pre-aligned. The big 
SHA1 calls are for pack-file verification in fsck, which should all be 
aligned. Same goes for index file integrity checking.

The actual object SHA1 calculations are likely not aligned (we do that 
object header thing), and if you can't do the htonl() any better way I 
guess the byte-based thing is the way to go..

		Linus

---
 block-sha1/sha1.c |   13 ++++++++++++-
 1 files changed, 12 insertions(+), 1 deletions(-)

diff --git a/block-sha1/sha1.c b/block-sha1/sha1.c
index 9bc8b8a..df27e66 100644
--- a/block-sha1/sha1.c
+++ b/block-sha1/sha1.c
@@ -25,6 +25,12 @@ void blk_SHA1_Init(blk_SHA_CTX *ctx)
 	ctx->H[4] = 0xc3d2e1f0;
 }
 
+#ifdef REALLY_SLOW_UNALIGNED
+  #define is_unaligned(ptr) (3 & (unsigned long)(ptr))
+#else
+  #define is_unaligned(ptr) 0
+#endif
+
 
 void blk_SHA1_Update(blk_SHA_CTX *ctx, const void *data, unsigned long len)
 {
@@ -47,7 +53,12 @@ void blk_SHA1_Update(blk_SHA_CTX *ctx, const void *data, unsigned long len)
 		blk_SHA1Block(ctx, ctx->W);
 	}
 	while (len >= 64) {
-		blk_SHA1Block(ctx, data);
+		const unsigned int *block = data;
+		if (is_unaligned(data)) {
+			memcpy(ctx->W, data, 64);
+			block = ctx->W;
+		}
+		blk_SHA1Block(ctx, block);
 		data += 64;
 		len -= 64;
 	}

^ permalink raw reply related

* Re: [PATCH] Re: [TRIVIAL] Documentation: add: <filepattern>... is optional
From: Paul Bolle @ 2009-08-11 15:06 UTC (permalink / raw)
  To: Nicolas Sebrecht; +Cc: Junio C Hamano, git
In-Reply-To: <20090811145041.GB12956@vidovic>

On Tue, 2009-08-11 at 16:50 +0200, Nicolas Sebrecht wrote:
> The 11/08/09, Paul Bolle wrote:
> 
> > <filepattern>... is optional (e.g. when the --all or --update
> > options are used) so use square brackets in the synopsis.
> 
> So <filepattern> is needed in all other cases.

Since it is an optional argument in those cases I'd say it is better to
indicate that it is optional in the synopsis too.


Paul Bolle

^ permalink raw reply

* Re: block-sha1: improve code on large-register-set machines
From: Nicolas Pitre @ 2009-08-11  6:15 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Git Mailing List, Junio C Hamano
In-Reply-To: <alpine.LFD.2.01.0908101637440.3417@localhost.localdomain>

On Mon, 10 Aug 2009, Linus Torvalds wrote:

> 
> For x86 performance (especially in 32-bit mode) I added that hack to write 
> the SHA1 internal temporary hash using a volatile pointer, in order to get 
> gcc to not try to cache the array contents. Because gcc will do all the 
> wrong things, and then spill things in insane random ways.
> 
> But on architectures like PPC, where you have 32 registers, it's actually 
> perfectly reasonable to put the whole temporary array[] into the register 
> set, and gcc can do so.
> 
> So make the 'volatile unsigned int *' cast be dependent on a 
> SMALL_REGISTER_SET preprocessor symbol, and enable it (currently) on just 
> x86 and x86-64.  With that, the routine is fairly reasonable even when 
> compared to the hand-scheduled PPC version. Ben Herrenschmidt reports on 
> a G5:
> 
>  * Paulus asm version:       about 3.67s
>  * Yours with no change:     about 5.74s
>  * Yours without "volatile": about 3.78s
> 
> so with this the C version is within about 3% of the asm one.
> 
> And add a lot of commentary on what the heck is going on.
> 
> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
> ---
> 
> I also asked David Miller to test the non-volatile version on Sparc, but I 
> suspect it will have the same pattern. ia64 likewise (but I have not asked 
> anybody to test).
> 
> Of the other architectures, ARM probably would wants SMALL_REGISTER_SET, 
> but I suspect the problem there is the htonl() (on little-endian), and 
> possibly the unaligned loads - at least on older ARM. The latter is 
> something gcc could be taught about, though (the SHA_SRC macro would just 
> need to use a pointer that goes through a packed struct member or 
> something).

The "older" ARM (those that don't perform unaligned accesses in 
hardware) are still the majority by far in the field.

Here some numbers on ARM for 203247018 bytes.

MOZILLA_SHA1:	14.520s
ARM_SHA1:	 5.600s
OPENSSL:	 5.530s

BLK_SHA1:	 5.280s		[original]
BLK_SHA1:	 7.410s		[with SMALL_REGISTER_SET defined]
BLK_SHA1:	 7.480s		[with 'W(x)=(val);asm("":"+m" (W(x)))']
BLK_SHA1:	 4.980s		[with 'W(x)=(val);asm("":::"memory")']

At this point the generated assembly is pretty slick.  I bet the full 
memory barrier might help on x86 as well.

However the above BLK_SHA1 works only for aligned source buffers.  So 
let's define our own SHA_SRC to replace the htonl() (which should 
probably be ntohl() by the way) like this:

#define SHA_SRC(t) \
  ({ unsigned char *__d = (unsigned char *)&data[t]; \
     (__d[0] << 24) | (__d[1] << 16) | (__d[2] << 8) | (__d[3] << 0); })

And this provides the exact same performance as the ntohl() based 
version (4.980s) except that this now cope with unaligned buffers too.

Of course the BLK_SHA1 version is a pig since it is totally unrolled

   text    data     bss     dec     hex filename
   1220       0       0    1220     4c4 mozilla-sha1/sha1.o
    852       0       0     852     354 arm/sha1_arm.o
   6292       0       0    6292    1894 block-sha1/sha1.o

so the speed advantage has a significant (but relative) code size cost.


Nicolas

^ permalink raw reply

* RFC for 1.7: Do not checkout -b master origin/master on clone
From: Michael J Gruber @ 2009-08-11 15:17 UTC (permalink / raw)
  To: Git Mailing List

One common source of confusion for newcomers is the fact that master is
given such a special treatment in git. While it is certainly okay and
helpful to set up a default branch in a new repository (git init) it is
not at all clear why it should be treated specially in any other
situation, such as:

- Why is master the only local branch which git clone sets up (git
checkout -b master origin/master)?

- Why does git svn set up a local branch with an svn upstream which is
determined by latest svn commit at the time of the first git svn fetch?

This behaviour not only is hard to justify; in fact it gives users a
completely wrong impression: by pretending that master is special, but
also by hiding core concepts (distinguishing local/remote branches,
detached heads) from the user at a point where that very hiding leads to
confusion.

Under the hood, it is of course HEAD which is given special treatment
(and which in the majority of repos points to master), and git clone
sets up a local branch according to HEAD (and does some other guess work
when cloning bare repos), which means that git clone shows the same
"random" behaviour which git svn clone does: Which local branch is set
up by default depends on the current value of HEAD/most recent commit at
the time of the cloning operation.

So, I suggest that starting with git 1.7:

- git clone does not set up any local branches at all
- git svn fetch does not set up any local branches at all

Ducking under my desk...
Michael

^ permalink raw reply

* Re: [PATCH 5/8] Add a config option for remotes to specify a foreign  vcs
From: Bert Wesarg @ 2009-08-11 15:31 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Daniel Barkalow, git, Brian Gernhardt
In-Reply-To: <7v1vnk79lt.fsf@alter.siamese.dyndns.org>

On Mon, Aug 10, 2009 at 03:15, Junio C Hamano<gitster@pobox.com> wrote:
> Daniel Barkalow <barkalow@iabervon.org> writes:
>
>> If this is set, the url is not required, and the transport always uses
>> a helper named "git-remote-<value>".
>>
>> It is a separate configuration option in order to allow a sensible
>> configuration for foreign systems which either have no meaningful urls
>> for repositories or which require urls that do not specify the system
>> used by the repository at that location. However, this only affects
>> how the name of the helper is determined, not anything about the
>> interaction with the helper, and the contruction is such that, if the
>> foreign scm does happen to use a co-named url method, a url with that
>> method may be used directly.
>
> Personally, I do not like this.
>
> Why isn't it enough to define the canonical remote name git takes as
> "<name of the helper>:<whatever string the helper understands>"?

May I ask what will happen to these supported URL notations:


       o   [user@]host.xz:/path/to/repo.git/

       o   [user@]host.xz:~user/path/to/repo.git/

       o   [user@]host.xz:path/to/repo.git

this will bite you, if you have an ssh host alias named "<your
favorite helper name>".

Bert

^ permalink raw reply

* Re: block-sha1: improve code on large-register-set machines
From: Linus Torvalds @ 2009-08-11 15:43 UTC (permalink / raw)
  To: Nicolas Pitre; +Cc: Git Mailing List, Junio C Hamano
In-Reply-To: <alpine.LFD.2.00.0908102246210.10633@xanadu.home>



On Tue, 11 Aug 2009, Nicolas Pitre wrote:
> 
> BLK_SHA1:	 5.280s		[original]
> BLK_SHA1:	 7.410s		[with SMALL_REGISTER_SET defined]
> BLK_SHA1:	 7.480s		[with 'W(x)=(val);asm("":"+m" (W(x)))']
> BLK_SHA1:	 4.980s		[with 'W(x)=(val);asm("":::"memory")']
> 
> At this point the generated assembly is pretty slick.  I bet the full 
> memory barrier might help on x86 as well.

No, I had tested that earlier - single-word memory barrier for some reason 
gets _much_ better numbers at least on x86-64. We're talking

	linus            1.46       418.2
vs
	linus           2.004       304.6

kind of differences. With the "+m" it outperforms openssl (375-380MB/s).

The "volatile unsigned int *" cast looks pretty much like the "+m" version 
to me, but Arthur got a speedup from whatever gcc code generation 
differences on his P4.

The really fundamental and basic problem with gcc on this code is that gcc 
does not see _any_ difference what-so-ever between the five variables 
declared with

	unsigned int A, B, C, D, E;

and the sixteen variables declared with

	unsigned int array[16];

and considers those all to be 21 local variables. It really seems to think 
that they are all 100% equivalent, and gcc totally ignores me doing things 
like adding "register" to the A-E ones etc.

And if you are a compiler, and think that the routine has 21 equal 
register variables, you're going to do crazy reload sh*t when you have 
only 7 (or 15) GP registers. So doing that full memory barrier seems to 
just take that random situation, and force some random variable to be 
spilled (this is all from looking at the generated code, not from looking 
at gcc).

In contrast, with the _targeted_ thing ("you'd better write back into 
array[]") we force gcc to spill the array[16] values, and not the A-E 
ones, and that's why it seems to make such a big difference.

And no, I'm not sure why ARM apparently doesn't show the same behavior. Or 
maybe it does, but with an in-order core it doesn't matter as much which 
registers you keep reloading - you'll be serialized all the time _anyway_. 

			Linus

^ permalink raw reply

* [RFC PATCH v3 0/8] Sparse checkout
From: Nguyễn Thái Ngọc Duy @ 2009-08-11 15:43 UTC (permalink / raw)
  To: git, Johannes Schindelin, Junio C Hamano
  Cc: Nguyễn Thái Ngọc Duy

Continuing the endless RFCs of sparse checkout, this series drops the sparse hook
in favor of .git/info/sparse. Changes from the last version


  Prevent diff machinery from examining assume-unchanged entries on worktree

    "if (ce_uptodate(ce) || CE_VALID)" is updated, as well as the corresponding test


  Avoid writing to buffer in add_excludes_from_file_1()

    Splitted out from the old second patch, as suggested by Johannes


  Read .gitignore from index if it is assume-unchanged

    read_index_data() is renamed. Commit message mentions add_excludes_from_file()


  excluded_1(): support exclude "directories" in index

    This one is new because index does not have "directory", more comments in the patch


  dir.c: export excluded_1() and add_excludes_from_file_1()

    New too, exported for use in unpack-trees.c


  unpack-trees.c: generalize verify_* functions

    Splitted out of the old third patch for easier review


  Support sparse checkout in unpack_trees() and read-tree

    Read .git/info/sparse instead of .git/hooks/sparse

    
  --sparse for porcelains
    RFC patch

 Documentation/technical/api-directory-listing.txt |    3 +
 builtin-checkout.c                                |    4 +
 builtin-clean.c                                   |    5 +-
 builtin-ls-files.c                                |    4 +-
 builtin-merge.c                                   |    5 +-
 builtin-read-tree.c                               |    4 +-
 cache.h                                           |    3 +
 diff-lib.c                                        |    6 +-
 dir.c                                             |  101 +++++++++++------
 dir.h                                             |    4 +
 git-pull.sh                                       |    6 +-
 t/t1009-read-tree-sparse.sh                       |   47 ++++++++
 t/t3001-ls-files-others-exclude.sh                |   22 ++++
 t/t4039-diff-assume-unchanged.sh                  |   31 ++++++
 t/t7300-clean.sh                                  |   19 ++++
 unpack-trees.c                                    |  121 ++++++++++++++++++++-
 unpack-trees.h                                    |    3 +
 17 files changed, 340 insertions(+), 48 deletions(-)
 create mode 100755 t/t1009-read-tree-sparse.sh
 create mode 100755 t/t4039-diff-assume-unchanged.sh

^ permalink raw reply

* [RFC PATCH v3 1/8] Prevent diff machinery from examining assume-unchanged entries on worktree
From: Nguyễn Thái Ngọc Duy @ 2009-08-11 15:43 UTC (permalink / raw)
  To: git, Johannes Schindelin, Junio C Hamano
  Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <1250005446-12047-1-git-send-email-pclouds@gmail.com>


Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 diff-lib.c                       |    6 ++++--
 t/t4039-diff-assume-unchanged.sh |   31 +++++++++++++++++++++++++++++++
 2 files changed, 35 insertions(+), 2 deletions(-)
 create mode 100755 t/t4039-diff-assume-unchanged.sh

diff --git a/diff-lib.c b/diff-lib.c
index b7813af..e5b9fe0 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -162,7 +162,8 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
 		if (ce_uptodate(ce))
 			continue;
 
-		changed = check_removed(ce, &st);
+		/* If CE_VALID is set, don't look at workdir for file removal */
+		changed = (ce->ce_flags & CE_VALID) ? 0 : check_removed(ce, &st);
 		if (changed) {
 			if (changed < 0) {
 				perror(ce->name);
@@ -337,6 +338,8 @@ static void do_oneway_diff(struct unpack_trees_options *o,
 	struct rev_info *revs = o->unpack_data;
 	int match_missing, cached;
 
+	/* if the entry is not checked out, don't examine work tree */
+	cached = o->index_only || (idx && (idx->ce_flags & CE_VALID));
 	/*
 	 * Backward compatibility wart - "diff-index -m" does
 	 * not mean "do not ignore merges", but "match_missing".
@@ -344,7 +347,6 @@ static void do_oneway_diff(struct unpack_trees_options *o,
 	 * But with the revision flag parsing, that's found in
 	 * "!revs->ignore_merges".
 	 */
-	cached = o->index_only;
 	match_missing = !revs->ignore_merges;
 
 	if (cached && idx && ce_stage(idx)) {
diff --git a/t/t4039-diff-assume-unchanged.sh b/t/t4039-diff-assume-unchanged.sh
new file mode 100755
index 0000000..9d9498b
--- /dev/null
+++ b/t/t4039-diff-assume-unchanged.sh
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+test_description='diff with assume-unchanged entries'
+
+. ./test-lib.sh
+
+# external diff has been tested in t4020-diff-external.sh
+
+test_expect_success 'setup' '
+	echo zero > zero &&
+	git add zero &&
+	git commit -m zero &&
+	echo one > one &&
+	echo two > two &&
+	git add one two &&
+	git commit -m onetwo &&
+	git update-index --assume-unchanged one &&
+	echo borked >> one &&
+	test "$(git ls-files -v one)" = "h one"
+'
+
+test_expect_success 'diff-index does not examine assume-unchanged entries' '
+	git diff-index HEAD^ -- one | grep -q 5626abf0f72e58d7a153368ba57db4c673c0e171
+'
+
+test_expect_success 'diff-files does not examine assume-unchanged entries' '
+	rm one &&
+	test -z "$(git diff-files -- one)"
+'
+
+test_done
-- 
1.6.3.GIT

^ permalink raw reply related

* [RFC PATCH v3 2/8] Avoid writing to buffer in add_excludes_from_file_1()
From: Nguyễn Thái Ngọc Duy @ 2009-08-11 15:44 UTC (permalink / raw)
  To: git, Johannes Schindelin, Junio C Hamano
  Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <1250005446-12047-2-git-send-email-pclouds@gmail.com>

In the next patch, the buffer that is being used within
add_excludes_from_file_1() comes from another function and does not
have extra space to put \n at the end.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 dir.c |    5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/dir.c b/dir.c
index e05b850..1170d64 100644
--- a/dir.c
+++ b/dir.c
@@ -229,10 +229,9 @@ static int add_excludes_from_file_1(const char *fname,
 
 	if (buf_p)
 		*buf_p = buf;
-	buf[size++] = '\n';
 	entry = buf;
-	for (i = 0; i < size; i++) {
-		if (buf[i] == '\n') {
+	for (i = 0; i <= size; i++) {
+		if (i == size || buf[i] == '\n') {
 			if (entry != buf + i && entry[0] != '#') {
 				buf[i - (i && buf[i-1] == '\r')] = 0;
 				add_exclude(entry, base, baselen, which);
-- 
1.6.3.GIT

^ permalink raw reply related

* [RFC PATCH v3 4/8] excluded_1(): support exclude "directories" in index
From: Nguyễn Thái Ngọc Duy @ 2009-08-11 15:44 UTC (permalink / raw)
  To: git, Johannes Schindelin, Junio C Hamano
  Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <1250005446-12047-4-git-send-email-pclouds@gmail.com>

Index does not really have "directories", attempts to match "foo/"
against index will fail unless someone tries to reconstruct directories
from a list of file.

Observing that dtype in this function can never be NULL (otherwise
it would segfault), dtype NULL will be used to say "hey.. you are
matching against index" and behave properly.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
  Having dtype to segfault when dtype is NULL is nice, but I found
  no way else to sneak the new code in. Defining DT_INDEX may clash
  existing system definitions..


 dir.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/dir.c b/dir.c
index 66b485c..c990938 100644
--- a/dir.c
+++ b/dir.c
@@ -350,6 +350,12 @@ static int excluded_1(const char *pathname,
 			int to_exclude = x->to_exclude;
 
 			if (x->flags & EXC_FLAG_MUSTBEDIR) {
+				if (!dtype) {
+					if (!prefixcmp(pathname, exclude))
+						return to_exclude;
+					else
+						continue;
+				}
 				if (*dtype == DT_UNKNOWN)
 					*dtype = get_dtype(NULL, pathname, pathlen);
 				if (*dtype != DT_DIR)
-- 
1.6.3.GIT

^ permalink raw reply related

* [RFC PATCH v3 3/8] Read .gitignore from index if it is assume-unchanged
From: Nguyễn Thái Ngọc Duy @ 2009-08-11 15:44 UTC (permalink / raw)
  To: git, Johannes Schindelin, Junio C Hamano
  Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <1250005446-12047-3-git-send-email-pclouds@gmail.com>

In sparse checkout mode (aka CE_VALID or assume-unchanged) some files
may be missing from working directory. If some of those files are
.gitignore, it will affect how git excludes files.

Because those files are by definition "assume unchanged" we can
instead read them from index. This adds index as a prerequisite for
directory listing. At the moment directory listing is used by "git
clean", "git add", "git ls-files" and "git status"/"git commit" and
unpack_trees()-related commands.  These commands have been
checked/modified to populate index before doing directory listing.

add_excludes_from_file() does not enable this feature, because it
is used to read .git/info/exclude and some explicit files specified
by "git ls-files".

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 Documentation/technical/api-directory-listing.txt |    3 +
 builtin-clean.c                                   |    5 +-
 builtin-ls-files.c                                |    4 +-
 dir.c                                             |   66 ++++++++++++++------
 t/t3001-ls-files-others-exclude.sh                |   22 +++++++
 t/t7300-clean.sh                                  |   19 ++++++
 6 files changed, 97 insertions(+), 22 deletions(-)

diff --git a/Documentation/technical/api-directory-listing.txt b/Documentation/technical/api-directory-listing.txt
index 5bbd18f..7d0e282 100644
--- a/Documentation/technical/api-directory-listing.txt
+++ b/Documentation/technical/api-directory-listing.txt
@@ -58,6 +58,9 @@ The result of the enumeration is left in these fields::
 Calling sequence
 ----------------
 
+* Ensure the_index is populated as it may have CE_VALID entries that
+  affect directory listing.
+
 * Prepare `struct dir_struct dir` and clear it with `memset(&dir, 0,
   sizeof(dir))`.
 
diff --git a/builtin-clean.c b/builtin-clean.c
index 2d8c735..d917472 100644
--- a/builtin-clean.c
+++ b/builtin-clean.c
@@ -71,8 +71,11 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
 
 	dir.flags |= DIR_SHOW_OTHER_DIRECTORIES;
 
-	if (!ignored)
+	if (!ignored) {
+		if (read_cache() < 0)
+			die("index file corrupt");
 		setup_standard_excludes(&dir);
+	}
 
 	pathspec = get_pathspec(prefix, argv);
 	read_cache();
diff --git a/builtin-ls-files.c b/builtin-ls-files.c
index f473220..d1a23c4 100644
--- a/builtin-ls-files.c
+++ b/builtin-ls-files.c
@@ -481,6 +481,9 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
 		prefix_offset = strlen(prefix);
 	git_config(git_default_config, NULL);
 
+	if (read_cache() < 0)
+		die("index file corrupt");
+
 	argc = parse_options(argc, argv, prefix, builtin_ls_files_options,
 			ls_files_usage, 0);
 	if (show_tag || show_valid_bit) {
@@ -508,7 +511,6 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
 	pathspec = get_pathspec(prefix, argv);
 
 	/* be nice with submodule paths ending in a slash */
-	read_cache();
 	if (pathspec)
 		strip_trailing_slash_from_submodules();
 
diff --git a/dir.c b/dir.c
index 1170d64..66b485c 100644
--- a/dir.c
+++ b/dir.c
@@ -200,11 +200,36 @@ void add_exclude(const char *string, const char *base,
 	which->excludes[which->nr++] = x;
 }
 
+static void *read_assume_unchanged_from_index(const char *path, size_t *size)
+{
+	int pos, len;
+	unsigned long sz;
+	enum object_type type;
+	void *data;
+	struct index_state *istate = &the_index;
+
+	len = strlen(path);
+	pos = index_name_pos(istate, path, len);
+	if (pos < 0)
+		return NULL;
+	/* only applies to CE_VALID entries */
+	if (!(istate->cache[pos]->ce_flags & CE_VALID))
+		return NULL;
+	data = read_sha1_file(istate->cache[pos]->sha1, &type, &sz);
+	if (!data || type != OBJ_BLOB) {
+		free(data);
+		return NULL;
+	}
+	*size = xsize_t(sz);
+	return data;
+}
+
 static int add_excludes_from_file_1(const char *fname,
 				    const char *base,
 				    int baselen,
 				    char **buf_p,
-				    struct exclude_list *which)
+				    struct exclude_list *which,
+				    int check_index)
 {
 	struct stat st;
 	int fd, i;
@@ -212,20 +237,26 @@ static int add_excludes_from_file_1(const char *fname,
 	char *buf, *entry;
 
 	fd = open(fname, O_RDONLY);
-	if (fd < 0 || fstat(fd, &st) < 0)
-		goto err;
-	size = xsize_t(st.st_size);
-	if (size == 0) {
-		close(fd);
-		return 0;
+	if (fd < 0 || fstat(fd, &st) < 0) {
+		if (0 <= fd)
+			close(fd);
+		if (!check_index ||
+		    (buf = read_assume_unchanged_from_index(fname, &size)) == NULL)
+			return -1;
 	}
-	buf = xmalloc(size+1);
-	if (read_in_full(fd, buf, size) != size)
-	{
-		free(buf);
-		goto err;
+	else {
+		size = xsize_t(st.st_size);
+		if (size == 0) {
+			close(fd);
+			return 0;
+		}
+		buf = xmalloc(size);
+		if (read_in_full(fd, buf, size) != size) {
+			close(fd);
+			return -1;
+		}
+		close(fd);
 	}
-	close(fd);
 
 	if (buf_p)
 		*buf_p = buf;
@@ -240,17 +271,12 @@ static int add_excludes_from_file_1(const char *fname,
 		}
 	}
 	return 0;
-
- err:
-	if (0 <= fd)
-		close(fd);
-	return -1;
 }
 
 void add_excludes_from_file(struct dir_struct *dir, const char *fname)
 {
 	if (add_excludes_from_file_1(fname, "", 0, NULL,
-				     &dir->exclude_list[EXC_FILE]) < 0)
+				     &dir->exclude_list[EXC_FILE], 0) < 0)
 		die("cannot use %s as an exclude file", fname);
 }
 
@@ -301,7 +327,7 @@ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)
 		strcpy(dir->basebuf + stk->baselen, dir->exclude_per_dir);
 		add_excludes_from_file_1(dir->basebuf,
 					 dir->basebuf, stk->baselen,
-					 &stk->filebuf, el);
+					 &stk->filebuf, el, 1);
 		dir->exclude_stack = stk;
 		current = stk->baselen;
 	}
diff --git a/t/t3001-ls-files-others-exclude.sh b/t/t3001-ls-files-others-exclude.sh
index c65bca8..fdd5dd8 100755
--- a/t/t3001-ls-files-others-exclude.sh
+++ b/t/t3001-ls-files-others-exclude.sh
@@ -64,6 +64,8 @@ two/*.4
 echo '!*.2
 !*.8' >one/two/.gitignore
 
+allignores='.gitignore one/.gitignore one/two/.gitignore'
+
 test_expect_success \
     'git ls-files --others with various exclude options.' \
     'git ls-files --others \
@@ -85,6 +87,26 @@ test_expect_success \
        >output &&
      test_cmp expect output'
 
+test_expect_success 'setup sparse gitignore' '
+	git add $allignores &&
+	git update-index --assume-unchanged $allignores &&
+	rm $allignores
+'
+
+test_expect_success \
+    'git ls-files --others with various exclude options.' \
+    'git ls-files --others \
+       --exclude=\*.6 \
+       --exclude-per-directory=.gitignore \
+       --exclude-from=.git/ignore \
+       >output &&
+     test_cmp expect output'
+
+test_expect_success 'restore gitignore' '
+	git checkout $allignores &&
+	rm .git/index
+'
+
 cat > excludes-file <<\EOF
 *.[1-8]
 e*
diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh
index 929d5d4..4886d5f 100755
--- a/t/t7300-clean.sh
+++ b/t/t7300-clean.sh
@@ -22,6 +22,25 @@ test_expect_success 'setup' '
 
 '
 
+test_expect_success 'git clean with assume-unchanged .gitignore' '
+	git update-index --assume-unchanged .gitignore &&
+	rm .gitignore &&
+	mkdir -p build docs &&
+	touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
+	git clean &&
+	test -f Makefile &&
+	test -f README &&
+	test -f src/part1.c &&
+	test -f src/part2.c &&
+	test ! -f a.out &&
+	test ! -f src/part3.c &&
+	test -f docs/manual.txt &&
+	test -f obj.o &&
+	test -f build/lib.so &&
+	git update-index --no-assume-unchanged .gitignore &&
+	git checkout .gitignore
+'
+
 test_expect_success 'git clean' '
 
 	mkdir -p build docs &&
-- 
1.6.3.GIT

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox