* Re: possible 'git cp'/how does git detect copies
From: Mircea Bardac @ 2008-06-27 13:16 UTC (permalink / raw)
To: Git Mailing List
In-Reply-To: <8aa486160806270557w20ce622co1099bceec7bc90f9@mail.gmail.com>
Hi,
Santi Béjar wrote:
> On Fri, Jun 27, 2008 at 14:40, Mircea Bardac <dev@mircea.bardac.net> wrote:
>> I was looking today at duplicating a file but, I soon realized that there is
>> no 'git cp' command (this was the "deductive approach to git commands",
>> starting from git mv/rm/...). How does "git diff -C" detect copies (-C is
>> used for this, according to the documentation)?
>
> Did you followed the "See also −−find−copies−harder."?
I knew this from before but for some reason I forgot about it when I
tried it now. The documentation for "git diff -C" is a bit misleading. I
have originally tested on git 1.5.2.something and the documentation for
-C didn't point to --find-copies-harder. I've quickly installed 1.5.6.1
to test the behavior but not the man pages.
Looking over the online docs for 1.5.6.1, it appears that there is now a
reference to --find-copies-harder.
Even so, saying just that "Detect copies as well as renames." is not
enough, as it assumes that there is no restriction on the detection process.
From --find-copies-harder
"For performance reasons, by default, -C option finds copies only if the
original file of the copy was modified in the same changeset." should be
moved to -C.
>> On a very simple test, I couldn't see this working. I just copied one file,
>> added it, committed the change, ran "git diff -C HEAD^!". There is no place
>> saying that it's contents is copied from some other file (both files are in
>> the repository now).
>>
>> "git blame -C new_copied_file" also doesn't show the commits for the
>> original file.
>
> git blame -C -C new_copied_file
Ah, duplicating the parameter. Looking better over these options I have
noticed that --find-copies-harder for "git diff" can also be replaced
with an extra -C. A little bit of consistency would help: either
"-C -C", either "--find-copies-harder" in both git blame/diff. Removing
from the documentation the deprecated version but keeping the
implementation for backwards compatibility might be a solution.
Many thanks,
Mircea
P.S. I know that patches are encouraged and technically it's pretty
simple to create a documentation patch, but I have not yet formed myself
a workflow for sending patches via Git to a maillist (this is a pending
task for me)
--
http://mircea.bardac.net
^ permalink raw reply
* Re: An alternate model for preparing partial commits
From: Johannes Schindelin @ 2008-06-27 13:33 UTC (permalink / raw)
To: Robert Anderson; +Cc: Git Mailing List
In-Reply-To: <9af502e50806262350t6e794a92g7751147f1882965@mail.gmail.com>
Hi,
On Thu, 26 Jun 2008, Robert Anderson wrote:
> Seems to me the concept of the "index" is a half-baked version of what
> I really want, which is the ability to factor a working tree's changes
> into its constituent parts in preparation for committing them.
Half-baked is probably too strong a word.
What you are basically asking for is to have the working directory
as staging area, and to be able to stash away changes that are not to be
committed.
Now, this is not necessarily what everybody wants, which is why many
people are fine with the index.
Having said that, I played with the idea of a "git stash -i", which would
allow you to select the changes to stash away. (And by extension, "git
stash -e" using the "git add -e" command.)
Hmm?
Ciao,
Dscho
^ permalink raw reply
* Re: pread() over NFS (again) [1.5.5.4]
From: Christian Holtje @ 2008-06-27 13:44 UTC (permalink / raw)
To: J. Bruce Fields; +Cc: logank, Junio C Hamano, Shawn O. Pearce, git
In-Reply-To: <20080627025413.GA19568@fieldses.org>
On Jun 26, 2008, at 10:54 PM, J. Bruce Fields wrote:
> On Thu, Jun 26, 2008 at 04:36:27PM -0700, logank@sent.com wrote:
>> No, it seems to be a simple error-out in this case. We have 2.4.20
>> systems
>
> That version's for the client or the server?
For the bug I sent the information is:
Server:
Linux dev1 2.4.28 #3 SMP Tue Jan 18 14:59:40 EST 2005 i686 i686 i386
GNU/Linux
Red Hat Linux release 9 (Shrike)
Client:
Linux dev2 2.6.9-42.0.8.ELsmp #1 SMP Tue Jan 30 12:18:01 EST 2007
x86_64 x86_64 x86_64 GNU/Linux
CentOS release 4.4 (Final)
Ciao!
^ permalink raw reply
* Re: An alternate model for preparing partial commits
From: Miklos Vajna @ 2008-06-27 13:49 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Robert Anderson, Git Mailing List
In-Reply-To: <alpine.DEB.1.00.0806271408290.9925@racer>
[-- Attachment #1: Type: text/plain, Size: 921 bytes --]
On Fri, Jun 27, 2008 at 02:33:33PM +0100, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> Having said that, I played with the idea of a "git stash -i", which would
> allow you to select the changes to stash away. (And by extension, "git
> stash -e" using the "git add -e" command.)
If we are at it, git checkout -i is also something which may be useful,
like:
1) Do two unrelated changes in a file.
2) You realize one of them is unnecessary.
Currently what you can do is something like:
1) You stage the first hunk using git add -p
2) git commit
3) git checkout file
But this forces you to commit early, and to commit --amend later. It
would be nice to be able to completely drop a hunk without first
commiting.
(Feel free to point out if this is something bad, I just remember from
the past that darcs revert - which is like git checkout - had such an
interactive mode.)
[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply
* [PATCH, next version] git bisect: introduce 'fixed' and 'unfixed'
From: Johannes Schindelin @ 2008-06-27 13:48 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jeff King, git
In-Reply-To: <7vej6mbh3w.fsf@gitster.siamese.dyndns.org>
When you look for a fix instead of a regression, it can be quite hard
to twist your brain into choosing the correct bisect command between
'git bisect bad' and 'git bisect good'.
So introduce the commands 'git bisect fixed' and 'git bisect unfixed'.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
On Tue, 24 Jun 2008, Junio C Hamano wrote:
> Jeff King <peff@peff.net> writes:
>
> > On Tue, Jun 24, 2008 at 06:09:28PM +0100, Johannes Schindelin
> > wrote:
> >
> >> And this is my first attempt at a proper patch for it.
> >>
> >> Now with documentation, and hopefully all places where the
> >> user is being told about a "bad" commit.
> >
> > This looks reasonably sane to me. The only thing I can think
> > of that we're missing is that "git bisect visualize" will still
> > show the refs as "bisect/bad" and "bisect/good".
> >
> > To fix that, you'd have to ask people to start the bisect by
> > saying "I am bisecting to find a fix, not a breakage." And then
> > you could change the refnames and all of the messages as
> > appropriate.
>
> It probably is not just a good idea, but is a necessary fix, to
> remove confusion like this example that appears everywhere:
>
> > echo >&2 'You '$THEN'need to give me at least one good' \
> > - 'and one bad revisions.'
> > + 'and one bad (or fixed) revision.'
> > echo >&2 '(You can use "git bisect bad" and' \
> > '"git bisect good" for that.)'
>
> People who are reading the change Dscho did in the "patch" form
> may not notice it, but imagine how the above looks to the end user
> who was told that "new bisect can now look for fixes", who does
> not need to nor even want to know that the new feature is
> implemented by making bad and fixed synonyms.
>
> They need to mentally reword "good" into "unfixed" and "bisect
> bad" into "bisect fixed" while reading the output from the above
> pieces, but the point of this new "look for fixes" feature is they do
> not have to do the rewording anymore!
How about autodetecting from the user's last input what she meant?
Documentation/git-bisect.txt | 16 ++++++++++++++++
git-bisect.sh | 42 ++++++++++++++++++++++++++++++------------
2 files changed, 46 insertions(+), 12 deletions(-)
diff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt
index 3ca0d33..3fb3b11 100644
--- a/Documentation/git-bisect.txt
+++ b/Documentation/git-bisect.txt
@@ -26,6 +26,9 @@ on the subcommand:
git bisect log
git bisect run <cmd>...
+ git bisect fixed [<rev>]
+ git bisect unfixed [<rev>...]
+
This command uses 'git-rev-list --bisect' option to help drive the
binary search process to find which change introduced a bug, given an
old "good" commit object name and a later "bad" commit object name.
@@ -76,6 +79,19 @@ bad", and ask for the next bisection.
Until you have no more left, and you'll have been left with the first
bad kernel rev in "refs/bisect/bad".
+Searching for fixes instead of regressions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Sometimes you need to find a fix, not a regression. The bisection
+machinery is really the same for this, but it might be tricky to remember
+to mark a commit "bad" when it contains the fix.
+
+So synonyms for "bad" and "good" are available, "fixed" and "unfixed"
+respectively.
+
+To mark a commit that contains the fix, call "git bisect fixed", and
+"git bisect unfixed" if it does not contain the fix.
+
Bisect reset
~~~~~~~~~~~~
diff --git a/git-bisect.sh b/git-bisect.sh
index 8b11107..197489b 100755
--- a/git-bisect.sh
+++ b/git-bisect.sh
@@ -1,6 +1,6 @@
#!/bin/sh
-USAGE='[help|start|bad|good|skip|next|reset|visualize|replay|log|run]'
+USAGE='[help|start|bad|good|fixed|unfixed|skip|next|reset|visualize|replay|log|run]'
LONG_USAGE='git bisect help
print this long help message.
git bisect start [<bad> [<good>...]] [--] [<pathspec>...]
@@ -24,6 +24,13 @@ git bisect log
git bisect run <cmd>...
use <cmd>... to automatically bisect.
+When not looking for a regression, but a fix instead, you can use
+
+git bisect fixed [<rev>]
+ mark <rev> as having the fix you are looking for
+git bisect unfixed [<rev>]
+ mark <rev> as not having the fix you are looking for
+
Please use "git help bisect" to get the full man page.'
OPTIONS_SPEC=
@@ -32,6 +39,8 @@ require_work_tree
_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
+GOOD="good"
+BAD="bad"
sq() {
@@PERL@@ -e '
@@ -216,7 +225,7 @@ bisect_next_check() {
t,,good)
# have bad but not good. we could bisect although
# this is less optimum.
- echo >&2 'Warning: bisecting only with a bad commit.'
+ echo >&2 'Warning: bisecting only with a $BAD commit.'
if test -t 0
then
printf >&2 'Are you sure [Y/n]? '
@@ -230,10 +239,10 @@ bisect_next_check() {
echo >&2 'You need to start by "git bisect start".'
THEN='then '
}
- echo >&2 'You '$THEN'need to give me at least one good' \
- 'and one bad revisions.'
- echo >&2 '(You can use "git bisect bad" and' \
- '"git bisect good" for that.)'
+ echo >&2 'You '$THEN'need to give me at least one $GOOD' \
+ 'and one $BAD revision.'
+ echo >&2 '(You can use "git bisect $BAD" and' \
+ '"git bisect $GOOD" for that.)'
exit 1 ;;
esac
}
@@ -250,7 +259,7 @@ eval_rev_list() {
if [ $res -ne 0 ]; then
echo >&2 "'git rev-list --bisect-vars' failed:"
- echo >&2 "maybe you mistake good and bad revs?"
+ echo >&2 "maybe you mistake $GOOD and $BAD revs?"
exit $res
fi
@@ -324,7 +333,7 @@ exit_if_skipped_commits () {
_tried=$1
if expr "$_tried" : ".*[|].*" > /dev/null ; then
echo "There are only 'skip'ped commit left to test."
- echo "The first bad commit could be any of:"
+ echo "The first $BAD commit could be any of:"
echo "$_tried" | tr '[|]' '[\012]'
echo "We cannot bisect more!"
exit 2
@@ -351,12 +360,12 @@ bisect_next() {
eval "$eval" || exit
if [ -z "$bisect_rev" ]; then
- echo "$bad was both good and bad"
+ echo "$bad was both $GOOD and $BAD"
exit 1
fi
if [ "$bisect_rev" = "$bad" ]; then
exit_if_skipped_commits "$bisect_tried"
- echo "$bisect_rev is first bad commit"
+ echo "$bisect_rev is first $BAD commit"
git diff-tree --pretty $bisect_rev
exit 0
fi
@@ -474,7 +483,8 @@ bisect_run () {
cat "$GIT_DIR/BISECT_RUN"
- if grep "first bad commit could be any of" "$GIT_DIR/BISECT_RUN" \
+ if grep "first $BAD commit could be any of" \
+ "$GIT_DIR/BISECT_RUN" \
> /dev/null; then
echo >&2 "bisect run cannot continue any more"
exit $res
@@ -486,7 +496,8 @@ bisect_run () {
exit $res
fi
- if grep "is first bad commit" "$GIT_DIR/BISECT_RUN" > /dev/null; then
+ if grep "is first $BAD commit" \
+ "$GIT_DIR/BISECT_RUN" > /dev/null; then
echo "bisect run success"
exit 0;
fi
@@ -502,6 +513,13 @@ case "$#" in
cmd="$1"
shift
case "$cmd" in
+ fixed|unfixed)
+ BAD="fixed"
+ GOOD="unfixed"
+ test "$cmd" = fixed && cmd=bad
+ test "$cmd" = unfixed && cmd=good
+ esac
+ case "$cmd" in
help)
git bisect -h ;;
start)
--
1.5.6.173.gde14c
^ permalink raw reply related
* Re: pread() over NFS (again) [1.5.5.4]
From: Christian Holtje @ 2008-06-27 13:54 UTC (permalink / raw)
To: logank; +Cc: Junio C Hamano, Shawn O. Pearce, git
In-Reply-To: <65688C06-BB6A-4E95-A4B9-A1A7C206BE2E@sent.com>
On Jun 26, 2008, at 7:36 PM, logank@sent.com wrote:
> diff --git a/index-pack.c b/index-pack.c
> index 5ac91ba..85c8bdb 100644
> --- a/index-pack.c
> +++ b/index-pack.c
> @@ -313,7 +313,14 @@ static void *get_data_from_pack(struct
> object_entry *obj)
> src = xmalloc(len);
> data = src;
> do {
> + // It appears that if multiple threads read across NFS, the
> + // second read will fail. I know this is awful, but we wait for
> + // a little bit and try again.
> ssize_t n = pread(pack_fd, data + rdy, len - rdy, from + rdy);
> + if (n <= 0) {
> + sleep(1);
> + n = pread(pack_fd, data + rdy, len - rdy, from + rdy);
> + }
> if (n <= 0)
> die("cannot pread pack file: %s", strerror(errno));
> rdy += n;
This does work. But the "unpacking objects" phase becomes very slow.
I had 86 objects and I could see every time it did a sleep because the
counter would wait a second (or more) before the next object was
unpacked.
Ciao!
^ permalink raw reply
* Installation Guide
From: Chris Hapgood @ 2008-06-27 14:18 UTC (permalink / raw)
To: git
FYI, I have posted a noob installation guide for Egit here: http://cho.hapgoods.com/wordpress/?p=159
Chris Hapgood
cch1@hapgoods.com
^ permalink raw reply
* [PATCH/RFC] stash: introduce 'stash save --keep-index' option
From: SZEDER Gábor @ 2008-06-27 14:37 UTC (permalink / raw)
To: Björn Steinbrink; +Cc: Robert Anderson, Git Mailing List
In-Reply-To: <20080627071014.GA12344@atjola.homenet>
'git stash save' saves local modifications to a new stash, and runs 'git
reset --hard' to revert them to a clean index and work tree. When the
'--keep-index' option is specified, after that 'git reset --hard' the
previous contents of the index is restored and the work tree is updated
to match the index. This option is useful if the user wants to commit
only parts of his local modifications, but wants to test those parts
before committing.
Also add support for the completion of the new option, and add an
example use case to the documentation.
Signed-off-by: SZEDER Gábor <szeder@ira.uka.de>
---
On Fri, Jun 27, 2008 at 09:10:14AM +0200, Björn Steinbrink wrote:
> Hm, I use "stash" for that purpose, which leads to kind of the reverse
> of your approach. So I do sth. like this:
>
> - hack hack hack
> - Notice that I want to make two commits out of what I have in my
> working tree
> - git add -p -- stage what I want in the first commit
> - git commit -m tmp -- temporary commit
> - git stash -- stash away what doesn't belong in the first commit
> - git reset HEAD^ -- drop the temporary commit, with the changes kept
> in the working tree
> - test, fix bugs, read the diff, whatever
> - git commit -- this time for good
> - git stash apply -- get back the changes for the second commit
I used to do the same, so I have added a '--keep-index' option to 'git
stash save' to simplify this workflow. Have a look at the use case
added to the documentation to see, how you could spare the temporary
commit and the 'reset HEAD^'.
RFC, because I'm not quite confident with using plumbing like 'git
read-tree'... and there are no tests.
Documentation/git-stash.txt | 22 +++++++++++++++++++++-
contrib/completion/git-completion.bash | 13 ++++++++++++-
git-stash.sh | 22 ++++++++++++++++++----
3 files changed, 51 insertions(+), 6 deletions(-)
diff --git a/Documentation/git-stash.txt b/Documentation/git-stash.txt
index baa4f55..936864f 100644
--- a/Documentation/git-stash.txt
+++ b/Documentation/git-stash.txt
@@ -36,12 +36,15 @@ is also possible).
OPTIONS
-------
-save [<message>]::
+save [--keep-index] [<message>]::
Save your local modifications to a new 'stash', and run `git-reset
--hard` to revert them. This is the default action when no
subcommand is given. The <message> part is optional and gives
the description along with the stashed state.
++
+If the `--keep-index` option is used, all changes already added to the
+index are left intact.
list [<options>]::
@@ -169,6 +172,23 @@ $ git stash apply
... continue hacking ...
----------------------------------------------------------------
+Testing partial commits::
+
+You can use `git stash save --keep-index` when you want to make two or
+more commits out of the changes in the work tree, and you want to test
+each change before committing:
++
+----------------------------------------------------------------
+... hack hack hack ...
+$ git add --patch foo
+$ git stash save --keep-index
+$ build && run tests
+$ git commit -m 'First part'
+$ git stash apply
+$ build && run tests
+$ git commit -a -m 'Second part'
+----------------------------------------------------------------
+
SEE ALSO
--------
linkgit:git-checkout[1],
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index ebf7cde..9a15500 100755
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -1139,8 +1139,19 @@ _git_show ()
_git_stash ()
{
local subcommands='save list show apply clear drop pop create'
- if [ -z "$(__git_find_subcommand "$subcommands")" ]; then
+ local subcommand="$(__git_find_subcommand "$subcommands")"
+ if [ -z "$subcommand" ]; then
__gitcomp "$subcommands"
+ else
+ local cur="${COMP_WORDS[COMP_CWORD]}"
+ case "$subcommand,$cur" in
+ save,--*)
+ __gitcomp "--keep-index"
+ ;;
+ *)
+ COMPREPLY=()
+ ;;
+ esac
fi
}
diff --git a/git-stash.sh b/git-stash.sh
index 4938ade..92531a2 100755
--- a/git-stash.sh
+++ b/git-stash.sh
@@ -86,6 +86,13 @@ create_stash () {
}
save_stash () {
+ keep_index=
+ case "$1" in
+ --keep-index)
+ keep_index=t
+ shift
+ esac
+
stash_msg="$1"
if no_changes
@@ -104,6 +111,13 @@ save_stash () {
git update-ref -m "$stash_msg" $ref_stash $w_commit ||
die "Cannot save the current status"
printf 'Saved working directory and index state "%s"\n' "$stash_msg"
+
+ git reset --hard
+
+ if test -n "$keep_index" && test -n $i_tree
+ then
+ git read-tree --reset -u $i_tree
+ fi
}
have_stash () {
@@ -153,7 +167,8 @@ apply_stash () {
die "$*: no valid stashed state found"
unstashed_index_tree=
- if test -n "$unstash_index" && test "$b_tree" != "$i_tree"
+ if test -n "$unstash_index" && test "$b_tree" != "$i_tree" &&
+ test "$c_tree" != "$i_tree"
then
git diff-tree --binary $s^2^..$s^2 | git apply --cached
test $? -ne 0 &&
@@ -235,7 +250,7 @@ show)
;;
save)
shift
- save_stash "$*" && git-reset --hard
+ save_stash "$*"
;;
apply)
shift
@@ -268,8 +283,7 @@ pop)
if test $# -eq 0
then
save_stash &&
- echo '(To restore them type "git stash apply")' &&
- git-reset --hard
+ echo '(To restore them type "git stash apply")'
else
usage
fi
--
1.5.6.1.95.ge713
^ permalink raw reply related
* Re: Installation Guide
From: Johannes Schindelin @ 2008-06-27 14:43 UTC (permalink / raw)
To: Chris Hapgood; +Cc: git
In-Reply-To: <C413A5C4-6418-4AC5-A885-2CEA7F4575B6@gmail.com>
On Fri, 27 Jun 2008, Chris Hapgood wrote:
> FYI, I have posted a noob installation guide for Egit here:
> http://cho.hapgoods.com/wordpress/?p=159
Added to the Wiki.
^ permalink raw reply
* Re: BUG (v1.5.6.1): ./configure missing check for zlib.h
From: Jakub Narebski @ 2008-06-27 14:46 UTC (permalink / raw)
To: Mircea Bardac; +Cc: git
In-Reply-To: <4864DD65.1080402@mircea.bardac.net>
Mircea Bardac <dev@mircea.bardac.net> writes:
> $ ./configure
[...]
> configure: CHECKS for header files
Here ./configure check for existence of heder files, but only those
that can be skipped by defining some macro...
> configure: CHECKS for site configuration
...and here is check for --with-zlib=<path to zlib>
> configure: creating ./config.status
> config.status: creating config.mak.autogen
>
> $ make
> GIT_VERSION = 1.5.6.1
> * new build flags or prefix
> CC daemon.o
> In file included from daemon.c:1:
> cache.h:9:18: error: zlib.h: No such file or directory
> make: *** [daemon.o] Error 1
>
> (installing zlib1g-dev on Ubuntu 7.10 fixed the problem)
What should ./configure do (what ./configure for other programs
or packages do)?
You cannot compile git without zlib!
--
Jakub Narebski
Poland
ShadeHawk on #git
^ permalink raw reply
* Re: pread() over NFS (again) [1.5.5.4]
From: Trond Myklebust @ 2008-06-27 14:50 UTC (permalink / raw)
To: J. Bruce Fields
Cc: Junio C Hamano, logank, Shawn O. Pearce, Christian Holtje, git,
Trond Myklebust
In-Reply-To: <20080627025715.GB19568@fieldses.org>
On Thu, 2008-06-26 at 22:57 -0400, J. Bruce Fields wrote:
> On Thu, Jun 26, 2008 at 04:38:40PM -0700, Junio C Hamano wrote:
> > logank@sent.com writes:
> >
> > > On Jun 26, 2008, at 1:56 PM, Junio C Hamano wrote:
> > >
> > >>> "The file shouldn't be short unless someone truncated it, or there
> > >>> is a bug in index-pack. Neither is very likely, but I don't think
> > >>> we would want to retry pread'ing the same block forever.
> > >>
> > >> I don't think we would want to retry even once. Return value of 0
> > >> from
> > >> pread is defined to be an EOF, isn't it?
> > >
> > > No, it seems to be a simple error-out in this case. We have 2.4.20
> > > systems with nfs-utils 0.3.3 and used to frequently get the same error
> > > while pushing. I made a similar change back in February and haven't
> > > had a problem since:
> > >
> > > diff --git a/index-pack.c b/index-pack.c
> > > index 5ac91ba..85c8bdb 100644
> > > --- a/index-pack.c
> > > +++ b/index-pack.c
> > > @@ -313,7 +313,14 @@ static void *get_data_from_pack(struct
> > > object_entry *obj)
> > > src = xmalloc(len);
> > > data = src;
> > > do {
> > > + // It appears that if multiple threads read across NFS, the
> > > + // second read will fail. I know this is awful, but we wait for
> > > + // a little bit and try again.
> > > ssize_t n = pread(pack_fd, data + rdy, len - rdy, from + rdy);
> > > + if (n <= 0) {
> > > + sleep(1);
> > > + n = pread(pack_fd, data + rdy, len - rdy, from + rdy);
> > > + }
> > > if (n <= 0)
> > > die("cannot pread pack file: %s", strerror(errno));
> > > rdy += n;
> > >
> > > I use a sleep request since it seems less likely that the other thread
> > > will have an outstanding request after a second of waiting.
> >
> > Gaah. Don't we have NFS experts in house? Bruce, perhaps?
>
> Trond, you don't have any idea why a 2.6.9-42.0.8.ELsmp client (2.4.28
> server) might be returning spurious 0's from pread()?
>
> Seems like everything is happening from that one client--the file isn't
> being simultaneously accessed from the server or from another client.
Is the file only being read, or could there be a simultaneous write to
the same file? I'm surmising this could be an effect resulting from
simultaneous cache invalidations: prior to Linux 2.6.20 or so, we
weren't rigorously following the VFS/VM rules for page locking, and so
page cache invalidation in particular could have some curious
side-effects.
Cheers
Trond
--
Trond Myklebust
Linux NFS client maintainer
NetApp
Trond.Myklebust@netapp.com
www.netapp.com
^ permalink raw reply
* Determining if two commits are on a separate branch
From: Adr3nal D0S @ 2008-06-27 14:55 UTC (permalink / raw)
To: git
We are making extensive use of submodules at work and we have created
a number of extra scripts to simplify our usage. For example, there
is git-rstatus, which recursively reports status of all submodules.
I am working on another script to check whether or not a change to any
submodules jump branches. If we have commits like this:
A--B--C
\--D
I don't care if a submodule moves from A to C or B to C, but I do care
if a commit of the super-project would cause a jump from D to C or
revert from C to B, effectively dropping previously committed code on
the floor.
So, is there a "correct" or "best" way to determine if one commit's
SHA follows directly from another's SHA in the commit history?
^ permalink raw reply
* Re: Determining if two commits are on a separate branch
From: Michael J Gruber @ 2008-06-27 15:13 UTC (permalink / raw)
To: git
In-Reply-To: <308083c30806270755t4316be67u1f468b51bf475d28@mail.gmail.com>
Adr3nal D0S venit, vidit, dixit 27.06.2008 16:55:
> We are making extensive use of submodules at work and we have created
> a number of extra scripts to simplify our usage. For example, there
> is git-rstatus, which recursively reports status of all submodules.
>
> I am working on another script to check whether or not a change to any
> submodules jump branches. If we have commits like this:
>
> A--B--C
> \--D
>
> I don't care if a submodule moves from A to C or B to C, but I do care
> if a commit of the super-project would cause a jump from D to C or
> revert from C to B, effectively dropping previously committed code on
> the floor.
>
> So, is there a "correct" or "best" way to determine if one commit's
> SHA follows directly from another's SHA in the commit history?
"Directly" as in "is child of", or as in "connected by the DAG"?
"git rev-list C..B" lists all commits which are not in C but in B. If
this list is empty then B is "contained" in C. This is how you can test
for being connected by the DAG. For the graph above, all of the
following refspecs would return an empty list, indicating connectedness:
C..B
C..A
B..A
D..B
D..A
Are those the "good ones" in your case? Then you know how to test for
the bad guys ;)
Michael
^ permalink raw reply
* Re: Determining if two commits are on a separate branch
From: Santi Béjar @ 2008-06-27 15:17 UTC (permalink / raw)
To: Adr3nal D0S; +Cc: git
In-Reply-To: <308083c30806270755t4316be67u1f468b51bf475d28@mail.gmail.com>
On Fri, Jun 27, 2008 at 16:55, Adr3nal D0S <adr3nald0s@gmail.com> wrote:
[...]
> So, is there a "correct" or "best" way to determine if one commit's
> SHA follows directly from another's SHA in the commit history?
You can compute the merge-base of these two commits and if the base is
one of them then it is a fast-forward.
For example, in git.git:
$ git merge-base origin/next origin/master
d54467b8c319571b5dc433b1f7e471c4b0f21caf
$ git rev-parse origin/next origin/master
3e7d305293ce93d00d5e0e6371311f7caa94f497
d54467b8c319571b5dc433b1f7e471c4b0f21caf
The merge-base is origin/master so it is an ancestor of origin/next.
HTH
Santi
^ permalink raw reply
* Re: BUG (v1.5.6.1): ./configure missing check for zlib.h
From: Mircea Bardac @ 2008-06-27 15:15 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git
In-Reply-To: <m3prq3hr6n.fsf@localhost.localdomain>
Jakub Narebski wrote:
> Mircea Bardac <dev@mircea.bardac.net> writes:
>
>> $ ./configure
> [...]
>> configure: CHECKS for header files
>
> Here ./configure check for existence of heder files, but only those
> that can be skipped by defining some macro...
> [...]
>>
>> (installing zlib1g-dev on Ubuntu 7.10 fixed the problem)
>
> What should ./configure do (what ./configure for other programs
> or packages do)?
>
> You cannot compile git without zlib!
Well, as far as I know, if a program depends on any external headers,
they should *all* be checked, not only "those that can be skipped by
defining some macro" (I personally do not know which are these).
Mircea
--
http://mircea.bardac.net
^ permalink raw reply
* Re: BUG (v1.5.6.1): ./configure missing check for zlib.h
From: tom fogal @ 2008-06-27 15:07 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git
In-Reply-To: <m3prq3hr6n.fsf@localhost.localdomain>
Jakub Narebski <jnareb@gmail.com> writes:
> Mircea Bardac <dev@mircea.bardac.net> writes:
>
> > $ ./configure
> [...]
> > configure: CHECKS for header files
> > In file included from daemon.c:1:
> > cache.h:9:18: error: zlib.h: No such file or directory
> > make: *** [daemon.o] Error 1
> >
> > (installing zlib1g-dev on Ubuntu 7.10 fixed the problem)
>
> What should ./configure do (what ./configure for other programs
> or packages do)?
If one can determine during configure time that a required library is
not found, it (IMHO) is nice to give an error message and bomb out (via
AC_MSG_ERROR).
The AC macro archive has a zlib macro which does this, as an example:
http://autoconf-archive.cryp.to/check_zlib.html
I should note, however, that I disagree with that macro's logic in that
it `searches' for zlib if the user does not specify it. IMO, if the
user does not give a --with option, and it doesn't work `out of the
box' (without hacking FLAGS), macros should die with an error rather
than retry with changed FLAGS.
-tom
^ permalink raw reply
* Re: is rebase the same as merging every commit?
From: David Jeske @ 2008-06-27 15:39 UTC (permalink / raw)
To: Matthieu Moy; +Cc: Junio C Hamano, git
In-Reply-To: <vpqd4m349hk.fsf@bauges.imag.fr>
This example you provided Matthieu is exactly my confusion with rebase..
If I want to bring a 'broken feature-a' branch into my topic branch to build on
it, one commit of which is this:
> + int * x = malloc(sizeof(char));
if I merge, my tree looks like:
: /<--G<--H<--Qj jeske/topic1
: / /
: /<--P<------Q feature-a
: /
: -----A<---B<---C master
or if I rebase, it looks like:
: /<--G'<--H' jeske/topic1
: /
: /<--P<---Q feature-a
: /
: -----A<---B<---C master
-----
..and then through 'fixing' the patch, it ends up rebased and accepted onto the
mainline origin/master, as a single patch, which (among other things) changed
this line to:
> + int * x = malloc(sizeof(int));
...if I merged above, it will look like,
: /<--G<--H<--Qj jeske/topic1
: / /
: /<--P<------Q feature-a
: /
: -----A<---B<---C<---Q' master
...if I rebased above, it will look like:
: /<--G'<--H' jeske/topic1
: /
: /<--P<---Q feature-a
: /
: -----A<---B<---C<---Q' master
However, in both cases, because Q' is not connected to Q, I don't see how git
will do anything sane to help me accept Q' correctly.
If I rebased my merge-q-branch against the master, I would expect to get this
(which will cause a conflict I have to resolve):
: /<--G<--H<--Qj jeske/topic1
: /
: <--C<---Q' master
If I rebased my rebase-q-branch against master, I would expect to get this
(which will cause a conflict I have to resolve):
: /<--G'<--H' jeske/topic1
: /
: /<--P<---Q feature-a
: /
: --C<---Q' master
However, if that Q' rebase contained a link back to (P,Q), it would know that
the Q' rebase was replacing (P,Q), and would know to back them out of my tree
when I rebased back onto the head, producing this in BOTH cases above (whether
I rebased or merged from the feature-a branch):
: /<--G'<--H' jeske/topic1
: /
: --C<---Q' master
This operation above of "working will pulling uncompleted patches into my tree"
seems like a fairly common thing for developers. I've never provided any
patches to linux-kernel, but when I did try hacking on it years ago, I was
doing exactly this. (pulling unaccepted patches into my kernel, then building
on those patches). When I read about the DAG and its universal naming, I always
assumed that the above workflow was what it was DESIGNED to make automatic. I'm
confused, how does this work in git?
-- Matthieu Moy wrote:
> Well, look at the [PATCH] messages on this list, and how they evolve.
> Patch series give a clean way to go from a point to another. That's
> what you want to see in upstream history.
>
> Then, patch series usually get reviewed, and the patches themselves
> are modified. There's a kind of meta-history: the changes you make to
> your own changes.
>
> Suppose I send a patch containing
>
> + int * x = malloc(sizeof(char));
>
> and someone notices how wrong it is. I send another patch with
>
> + int * x = malloc(sizeof(int));
>
> The first version was basicaly a mistake, and if it hasn't been
> released, no one want to bother with it longer that the time to resend
> the patch. No one want to be hit by the bug while using bisect later
> on the upstream repository. And no one wants to see both patches when
> reviewing or "git blame"-ing.
^ permalink raw reply
* Re: is rebase the same as merging every commit?
From: David Jeske @ 2008-06-27 15:39 UTC (permalink / raw)
To: Matthieu Moy; +Cc: Junio C Hamano, git
In-Reply-To: <vpqd4m349hk.fsf@bauges.imag.fr>
This example you provided Matthieu is exactly my confusion with rebase..
If I want to bring a 'broken feature-a' branch into my topic branch to build on
it, one commit of which is this:
> + int * x = malloc(sizeof(char));
if I merge, my tree looks like:
: /<--G<--H<--Qj jeske/topic1
: / /
: /<--P<------Q feature-a
: /
: -----A<---B<---C master
or if I rebase, it looks like:
: /<--G'<--H' jeske/topic1
: /
: /<--P<---Q feature-a
: /
: -----A<---B<---C master
-----
..and then through 'fixing' the patch, it ends up rebased and accepted onto the
mainline origin/master, as a single patch, which (among other things) changed
this line to:
> + int * x = malloc(sizeof(int));
...if I merged above, it will look like,
: /<--G<--H<--Qj jeske/topic1
: / /
: /<--P<------Q feature-a
: /
: -----A<---B<---C<---Q' master
...if I rebased above, it will look like:
: /<--G'<--H' jeske/topic1
: /
: /<--P<---Q feature-a
: /
: -----A<---B<---C<---Q' master
However, in both cases, because Q' is not connected to Q, I don't see how git
will do anything sane to help me accept Q' correctly.
If I rebased my merge-q-branch against the master, I would expect to get this
(which will cause a conflict I have to resolve):
: /<--G<--H<--Qj jeske/topic1
: /
: <--C<---Q' master
If I rebased my rebase-q-branch against master, I would expect to get this
(which will cause a conflict I have to resolve):
: /<--G'<--H' jeske/topic1
: /
: /<--P<---Q feature-a
: /
: --C<---Q' master
However, if that Q' rebase contained a link back to (P,Q), it would know that
the Q' rebase was replacing (P,Q), and would know to back them out of my tree
when I rebased back onto the head, producing this in BOTH cases above (whether
I rebased or merged from the feature-a branch):
: /<--G'<--H' jeske/topic1
: /
: --C<---Q' master
This operation above of "working will pulling uncompleted patches into my tree"
seems like a fairly common thing for developers. I've never provided any
patches to linux-kernel, but when I did try hacking on it years ago, I was
doing exactly this. (pulling unaccepted patches into my kernel, then building
on those patches). When I read about the DAG and its universal naming, I always
assumed that the above workflow was what it was DESIGNED to make automatic. I'm
confused, how does this work in git?
-- Matthieu Moy wrote:
> Well, look at the [PATCH] messages on this list, and how they evolve.
> Patch series give a clean way to go from a point to another. That's
> what you want to see in upstream history.
>
> Then, patch series usually get reviewed, and the patches themselves
> are modified. There's a kind of meta-history: the changes you make to
> your own changes.
>
> Suppose I send a patch containing
>
> + int * x = malloc(sizeof(char));
>
> and someone notices how wrong it is. I send another patch with
>
> + int * x = malloc(sizeof(int));
>
> The first version was basicaly a mistake, and if it hasn't been
> released, no one want to bother with it longer that the time to resend
> the patch. No one want to be hit by the bug while using bisect later
> on the upstream repository. And no one wants to see both patches when
> reviewing or "git blame"-ing.
^ permalink raw reply
* Re: [PATCH 1/2] clone: respect the settings in $HOME/.gitconfig and /etc/gitconfig
From: Daniel Barkalow @ 2008-06-27 16:05 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Pieter de Bie, Git Mailinglist, Junio C Hamano
In-Reply-To: <alpine.DEB.1.00.0806271353350.9925@racer>
On Fri, 27 Jun 2008, Johannes Schindelin wrote:
> After initializing the config in the newly-created repository, we
> need to unset GIT_CONFIG so that the global configs are read again.
This seems fine to me. OTOH, I'm not sure the environment variable should
be needed in the first place; I think the config stuff should look in
git_path("config") without it, and we set the git dir to the one we're
initializing. So I think the use of the environment variable is just an
artifact of how the shell script did it and how I was originally calling
the init_db stuff.
Just removing the "setenv()" line survives all of the tests for me, and I
remember some of them failing before I'd gotten some sort of solution for
the config stuff.
> Noticed by Pieter de Bie.
You'd think I would have noticed this, since I mainly decided to convert
clone to C so that url.insteadOf in global config would let you do "git
clone work:modulename", but I clearly never tested it.
> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> ---
>
> On Fri, 27 Jun 2008, Pieter de Bie wrote:
>
> > I sometimes use url.insteadOf to create a shortcut to a central
> > repository. For example, having something like[*1*]
> >
> > [url "git://repo.or.cz/git/"]
> > insteadOf = "repo:"
> >
> > in my global gitconfig allows me to do a 'git fetch
> > repo:dscho.git'. I'd also like to use that with git clone :).
> > Currently if I try that, I get
> >
> > Vienna:~ pieter$ git clone repo:dscho.git
> > Initialize dscho/.git
> > Initialized empty Git repository in /Users/pieter/dscho/.git/
> > ssh: Error resolving hostname repo: nodename nor servname provided,
> > or not known
> > fatal: The remote end hung up unexpectedly
> >
> > [...]
> >
> > Is there an easy fix for this?
>
> Yes ;-)
>
> builtin-clone.c | 7 +++++++
> 1 files changed, 7 insertions(+), 0 deletions(-)
>
> diff --git a/builtin-clone.c b/builtin-clone.c
> index 17baa20..965b5fc 100644
> --- a/builtin-clone.c
> +++ b/builtin-clone.c
> @@ -424,6 +424,13 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
> fprintf(stderr, "Initialize %s\n", git_dir);
> init_db(option_template, option_quiet ? INIT_DB_QUIET : 0);
>
> + /*
> + * At this point, the config exists, so we do not need the
> + * environment variable. We actually need to unset it, too, to
> + * re-enable parsing of the global configs.
> + */
> + unsetenv(CONFIG_ENVIRONMENT);
> +
> if (option_reference)
> setup_reference(git_dir);
>
> --
> 1.5.6.173.gde14c
>
>
^ permalink raw reply
* Re: [PATCH 2/2] clone: respect url.insteadOf setting in global configs
From: Daniel Barkalow @ 2008-06-27 16:08 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Pieter de Bie, Git Mailinglist, Junio C Hamano
In-Reply-To: <alpine.DEB.1.00.0806271355520.9925@racer>
On Fri, 27 Jun 2008, Johannes Schindelin wrote:
> When we call "git clone" with a url that has a rewrite rule in either
> $HOME/.gitconfig or /etc/gitconfig, the URL can be different from
> what the command line expects it to be.
>
> So, let's use the URL as the remote structure has it, not the literal
> string from the command line.
This is how it should be.
Maybe I ought to make transport_get() take the index of the URL in the
list for the remote, instead of taking the actual URL; any use of a URL
that's not from that list is going to be oddly wrong in some way, I think.
Thanks for taking care of this.
> Noticed by Pieter de Bie.
>
> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> ---
> builtin-clone.c | 3 ++-
> 1 files changed, 2 insertions(+), 1 deletions(-)
>
> diff --git a/builtin-clone.c b/builtin-clone.c
> index 965b5fc..8dda52a 100644
> --- a/builtin-clone.c
> +++ b/builtin-clone.c
> @@ -463,7 +463,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
> refs = clone_local(path, git_dir);
> else {
> struct remote *remote = remote_get(argv[0]);
> - struct transport *transport = transport_get(remote, argv[0]);
> + struct transport *transport =
> + transport_get(remote, remote->url[0]);
>
> if (!transport->get_refs_list || !transport->fetch)
> die("Don't know how to clone %s", transport->url);
> --
> 1.5.6.173.gde14c
>
>
>
^ permalink raw reply
* Re: 'next' will be rewound shortly
From: Stephan Beyer @ 2008-06-27 16:12 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vzlphvl69.fsf_-_@gitster.siamese.dyndns.org>
Hi Junio,
> Following the new tradition we began a few releases ago, I'll rewind the
> tip of 'next' shortly. Two topics will be kicked back to 'pu' while we
> are at it (jc/send-pack-tell-me-more and js/rebase-i-sequencer).
I wonder why the bugfix commit
aec7e9cd Don't append default merge message to -m message
has disappeared or why/if this belongs to js/rebase-i-sequencer.
I noticed this because a test case of sequencer failed during rebasing
to pure "master"/"next" without js/rebase-i-sequencer.
I also have a question:
my development branch for the sequencer prototype is based on next,
then:
* Merge js/rebase-i-sequencer
* ... development ...
The only reason that makes js/rebase-i-sequencer important (besides
aec7e9cd which is mentioned above), is for the last patch
("Migrate rebase-i to use sequencer") in the patchset that I want to
send to the list. (Otherwise a lot of work of Joerg Sommer would be
annotated to me.)
So I wanted to
1. send a patchset based on "master"/"next" without the rebase-i
feature extentions of Joerg Sommer, and
2. resend the last patch (the one about rebase-i) based on "pu",
where js/rebase-i-sequencer is still merged into.
Is this sane?
(The other variant could be that I send the "Merge js/rebase-i-sequencer"
commit as a patch to the list, but this sounds insane to me.)
Regards,
Stephan
--
Stephan Beyer <s-beyer@gmx.net>, PGP 0x6EDDD207FCC5040F
^ permalink raw reply
* [PATCH 01/15] Move split_cmdline() to alias.c
From: Miklos Vajna @ 2008-06-27 16:21 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Johannes Schindelin, Olivier Marin, Junio C Hamano
In-Reply-To: <cover.1214581610.git.vmiklos@frugalware.org>
split_cmdline() is currently used for aliases only, but later it can be
useful for other builtins as well. Move it to alias.c for now,
indicating that originally it's for aliases, but we'll have it in libgit
this way.
Signed-off-by: Miklos Vajna <vmiklos@frugalware.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
alias.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
cache.h | 1 +
git.c | 53 -----------------------------------------------------
3 files changed, 55 insertions(+), 53 deletions(-)
diff --git a/alias.c b/alias.c
index 995f3e6..ccb1108 100644
--- a/alias.c
+++ b/alias.c
@@ -21,3 +21,57 @@ char *alias_lookup(const char *alias)
git_config(alias_lookup_cb, NULL);
return alias_val;
}
+
+int split_cmdline(char *cmdline, const char ***argv)
+{
+ int src, dst, count = 0, size = 16;
+ char quoted = 0;
+
+ *argv = xmalloc(sizeof(char*) * size);
+
+ /* split alias_string */
+ (*argv)[count++] = cmdline;
+ for (src = dst = 0; cmdline[src];) {
+ char c = cmdline[src];
+ if (!quoted && isspace(c)) {
+ cmdline[dst++] = 0;
+ while (cmdline[++src]
+ && isspace(cmdline[src]))
+ ; /* skip */
+ if (count >= size) {
+ size += 16;
+ *argv = xrealloc(*argv, sizeof(char*) * size);
+ }
+ (*argv)[count++] = cmdline + dst;
+ } else if (!quoted && (c == '\'' || c == '"')) {
+ quoted = c;
+ src++;
+ } else if (c == quoted) {
+ quoted = 0;
+ src++;
+ } else {
+ if (c == '\\' && quoted != '\'') {
+ src++;
+ c = cmdline[src];
+ if (!c) {
+ free(*argv);
+ *argv = NULL;
+ return error("cmdline ends with \\");
+ }
+ }
+ cmdline[dst++] = c;
+ src++;
+ }
+ }
+
+ cmdline[dst] = 0;
+
+ if (quoted) {
+ free(*argv);
+ *argv = NULL;
+ return error("unclosed quote");
+ }
+
+ return count;
+}
+
diff --git a/cache.h b/cache.h
index c8954ef..d5463d8 100644
--- a/cache.h
+++ b/cache.h
@@ -830,5 +830,6 @@ int report_path_error(const char *ps_matched, const char **pathspec, int prefix_
void overlay_tree_on_cache(const char *tree_name, const char *prefix);
char *alias_lookup(const char *alias);
+int split_cmdline(char *cmdline, const char ***argv);
#endif /* CACHE_H */
diff --git a/git.c b/git.c
index 59f0fcc..2fbe96b 100644
--- a/git.c
+++ b/git.c
@@ -90,59 +90,6 @@ static int handle_options(const char*** argv, int* argc, int* envchanged)
return handled;
}
-static int split_cmdline(char *cmdline, const char ***argv)
-{
- int src, dst, count = 0, size = 16;
- char quoted = 0;
-
- *argv = xmalloc(sizeof(char*) * size);
-
- /* split alias_string */
- (*argv)[count++] = cmdline;
- for (src = dst = 0; cmdline[src];) {
- char c = cmdline[src];
- if (!quoted && isspace(c)) {
- cmdline[dst++] = 0;
- while (cmdline[++src]
- && isspace(cmdline[src]))
- ; /* skip */
- if (count >= size) {
- size += 16;
- *argv = xrealloc(*argv, sizeof(char*) * size);
- }
- (*argv)[count++] = cmdline + dst;
- } else if(!quoted && (c == '\'' || c == '"')) {
- quoted = c;
- src++;
- } else if (c == quoted) {
- quoted = 0;
- src++;
- } else {
- if (c == '\\' && quoted != '\'') {
- src++;
- c = cmdline[src];
- if (!c) {
- free(*argv);
- *argv = NULL;
- return error("cmdline ends with \\");
- }
- }
- cmdline[dst++] = c;
- src++;
- }
- }
-
- cmdline[dst] = 0;
-
- if (quoted) {
- free(*argv);
- *argv = NULL;
- return error("unclosed quote");
- }
-
- return count;
-}
-
static int handle_alias(int *argcp, const char ***argv)
{
int envchanged = 0, ret = 0, saved_errno = errno;
--
1.5.6
^ permalink raw reply related
* [PATCH 00/15] Build in merge
From: Miklos Vajna @ 2008-06-27 16:21 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Johannes Schindelin, Olivier Marin
Hello,
Dscho gave me a detailed review on builtin-merge, so I'm sending an
updated series.
It's based on 49646c5 in git.git, so hopefully it includes all the work
Junio did recently in 'pu'. (PARSE_OPT_ARGV0_IS_AN_OPTION removal, etc.)
Changes:
* "git-fmt-merge-msg: make it usable from other builtins"
- Small cleanup.
* "Build in merge"
- When a custom message was given for a merge, the result was not
identical to the one git-merge.sh had. I added a testcase for this
and fixed up builtin-merge to pass the test.
- Memleak fix in restore_state()
- Cleanup in finish_up_to_date() and squash_message()
- run_hook() now first checks if the executable bit is set and returns
immediately if not.
- Make merge_name() a bit more readable, like *(ptr+1) -> ptr[1]. Also
fixed a missing initialization in this function.
- split_merge_strategies(): while (1) -> for (;;)
- Simplified path_list_append_strategy() by removing unnecessary
parameters.
- cmd_merge(): Added more comments to make the code more readable,
fixed a memory leak, optimized the case when --no-commit is used.
- merge_one_remote(): Fixed a bug which for example caused a segfault
when building with -fno-inline.
- Fixed up color handling when showing the diff after a merge, as
noticed by Olivier Marin.
- Fixed up the "Updating foo..bar" message which was like "Updating
bar..bar", as pointed out by Olivier Marin.
* Dscho's two patches: These introduces strbuf_initf() which can be used
instead of strbuf_init() and strbuf_addf(). Modified builtin-merge.c
to use strbuf_initf() where possible.
* Extended t7601-merge-pull-config.sh to make sure git-merge picks up
the best strategy when no strategy can handle the merge without
conflicts.
The "interdiff" is available via git diff 49646c5..d1c62b2 in
git://repo.or.cz/git/vmiklos.git.
I'm sending the whole series to avoid complexity, but in fact I only
changed the following patches:
* "git-fmt-merge-msg: make it usable from other builtins"
* "Add new test case to ensure git-merge prepends the custom merge
message"
* "Build in merge"
Johannes Schindelin (2):
Add strbuf_vaddf(), use it in strbuf_addf(), and add strbuf_initf()
strbuf_vaddf(): support %*s, too
Junio C Hamano (2):
Introduce get_merge_bases_many()
Introduce reduce_heads()
Miklos Vajna (11):
Move split_cmdline() to alias.c
Move commit_list_count() to commit.c
Move parse-options's skip_prefix() to git-compat-util.h
Add new test to ensure git-merge handles pull.twohead and
pull.octopus
Move read_cache_unmerged() to read-cache.c
git-fmt-merge-msg: make it usable from other builtins
Introduce get_octopus_merge_bases() in commit.c
Add new test to ensure git-merge handles more than 25 refs.
Add new test case to ensure git-merge reduces octopus parents when
possible
Add new test case to ensure git-merge prepends the custom merge
message
Build in merge
.gitignore | 1 +
Makefile | 6 +-
alias.c | 54 ++
builtin-fmt-merge-msg.c | 155 ++--
builtin-merge-recursive.c | 8 -
builtin-merge.c | 1143 +++++++++++++++++++++++++
builtin-read-tree.c | 24 -
builtin-remote.c | 39 +-
builtin.h | 4 +
cache.h | 3 +
commit.c | 136 +++-
commit.h | 4 +
git-merge.sh => contrib/examples/git-merge.sh | 0
git-compat-util.h | 6 +
git.c | 54 +--
parse-options.c | 6 -
read-cache.c | 31 +
strbuf.c | 140 +++-
strbuf.h | 3 +
t/t0000-basic.sh | 8 +
t/t7601-merge-pull-config.sh | 129 +++
t/t7602-merge-octopus-many.sh | 52 ++
t/t7603-merge-reduce-heads.sh | 63 ++
t/t7604-merge-custom-message.sh | 37 +
test-strbuf.c | 17 +
25 files changed, 1917 insertions(+), 206 deletions(-)
create mode 100644 builtin-merge.c
rename git-merge.sh => contrib/examples/git-merge.sh (100%)
create mode 100755 t/t7601-merge-pull-config.sh
create mode 100755 t/t7602-merge-octopus-many.sh
create mode 100755 t/t7603-merge-reduce-heads.sh
create mode 100755 t/t7604-merge-custom-message.sh
create mode 100644 test-strbuf.c
^ permalink raw reply
* [PATCH 07/15] Introduce get_octopus_merge_bases() in commit.c
From: Miklos Vajna @ 2008-06-27 16:22 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Johannes Schindelin, Olivier Marin, Junio C Hamano
In-Reply-To: <cover.1214581610.git.vmiklos@frugalware.org>
This is like get_merge_bases() but it works for multiple heads, like
show-branch --merge-base.
Signed-off-by: Miklos Vajna <vmiklos@frugalware.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
commit.c | 27 +++++++++++++++++++++++++++
commit.h | 1 +
2 files changed, 28 insertions(+), 0 deletions(-)
diff --git a/commit.c b/commit.c
index bbf9c75..6052ca3 100644
--- a/commit.c
+++ b/commit.c
@@ -600,6 +600,33 @@ static struct commit_list *merge_bases(struct commit *one, struct commit *two)
return result;
}
+struct commit_list *get_octopus_merge_bases(struct commit_list *in)
+{
+ struct commit_list *i, *j, *k, *ret = NULL;
+ struct commit_list **pptr = &ret;
+
+ for (i = in; i; i = i->next) {
+ if (!ret)
+ pptr = &commit_list_insert(i->item, pptr)->next;
+ else {
+ struct commit_list *new = NULL, *end = NULL;
+
+ for (j = ret; j; j = j->next) {
+ struct commit_list *bases;
+ bases = get_merge_bases(i->item, j->item, 1);
+ if (!new)
+ new = bases;
+ else
+ end->next = bases;
+ for (k = bases; k; k = k->next)
+ end = k;
+ }
+ ret = new;
+ }
+ }
+ return ret;
+}
+
struct commit_list *get_merge_bases(struct commit *one,
struct commit *two, int cleanup)
{
diff --git a/commit.h b/commit.h
index 7f8c5ee..dcec7fb 100644
--- a/commit.h
+++ b/commit.h
@@ -121,6 +121,7 @@ int read_graft_file(const char *graft_file);
struct commit_graft *lookup_commit_graft(const unsigned char *sha1);
extern struct commit_list *get_merge_bases(struct commit *rev1, struct commit *rev2, int cleanup);
+extern struct commit_list *get_octopus_merge_bases(struct commit_list *in);
extern int register_shallow(const unsigned char *sha1);
extern int unregister_shallow(const unsigned char *sha1);
--
1.5.6
^ permalink raw reply related
* [PATCH 03/15] Move parse-options's skip_prefix() to git-compat-util.h
From: Miklos Vajna @ 2008-06-27 16:21 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Johannes Schindelin, Olivier Marin, Junio C Hamano
In-Reply-To: <cover.1214581610.git.vmiklos@frugalware.org>
builtin-remote.c and parse-options.c both have a skip_prefix() function,
for the same purpose. Move parse-options's one to git-compat-util.h and
let builtin-remote use it as well.
Signed-off-by: Miklos Vajna <vmiklos@frugalware.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
builtin-remote.c | 39 ++++++++++++++++++++++++++-------------
git-compat-util.h | 6 ++++++
parse-options.c | 6 ------
3 files changed, 32 insertions(+), 19 deletions(-)
diff --git a/builtin-remote.c b/builtin-remote.c
index 145dd85..1491354 100644
--- a/builtin-remote.c
+++ b/builtin-remote.c
@@ -29,12 +29,6 @@ static inline int postfixcmp(const char *string, const char *postfix)
return strcmp(string + len1 - len2, postfix);
}
-static inline const char *skip_prefix(const char *name, const char *prefix)
-{
- return !name ? "" :
- prefixcmp(name, prefix) ? name : name + strlen(prefix);
-}
-
static int opt_parse_track(const struct option *opt, const char *arg, int not)
{
struct path_list *list = opt->value;
@@ -182,12 +176,18 @@ static int config_read_branches(const char *key, const char *value, void *cb)
info->remote = xstrdup(value);
} else {
char *space = strchr(value, ' ');
- value = skip_prefix(value, "refs/heads/");
+ const char *ptr = skip_prefix(value, "refs/heads/");
+ if (ptr)
+ value = ptr;
while (space) {
char *merge;
merge = xstrndup(value, space - value);
path_list_append(merge, &info->merge);
- value = skip_prefix(space + 1, "refs/heads/");
+ ptr = skip_prefix(space + 1, "refs/heads/");
+ if (ptr)
+ value = ptr;
+ else
+ value = space + 1;
space = strchr(value, ' ');
}
path_list_append(xstrdup(value), &info->merge);
@@ -219,7 +219,12 @@ static int handle_one_branch(const char *refname,
refspec.dst = (char *)refname;
if (!remote_find_tracking(states->remote, &refspec)) {
struct path_list_item *item;
- const char *name = skip_prefix(refspec.src, "refs/heads/");
+ const char *name, *ptr;
+ ptr = skip_prefix(refspec.src, "refs/heads/");
+ if (ptr)
+ name = ptr;
+ else
+ name = refspec.src;
/* symbolic refs pointing nowhere were handled already */
if ((flags & REF_ISSYMREF) ||
unsorted_path_list_has_path(&states->tracked,
@@ -248,6 +253,7 @@ static int get_ref_states(const struct ref *ref, struct ref_states *states)
struct path_list *target = &states->tracked;
unsigned char sha1[20];
void *util = NULL;
+ const char *ptr;
if (!ref->peer_ref || read_ref(ref->peer_ref->name, sha1))
target = &states->new;
@@ -256,8 +262,10 @@ static int get_ref_states(const struct ref *ref, struct ref_states *states)
if (hashcmp(sha1, ref->new_sha1))
util = &states;
}
- path_list_append(skip_prefix(ref->name, "refs/heads/"),
- target)->util = util;
+ ptr = skip_prefix(ref->name, "refs/heads/");
+ if (!ptr)
+ ptr = ref->name;
+ path_list_append(ptr, target)->util = util;
}
free_refs(fetch_map);
@@ -522,10 +530,15 @@ static int show(int argc, const char **argv)
"es" : "");
for (i = 0; i < states.remote->push_refspec_nr; i++) {
struct refspec *spec = states.remote->push + i;
+ const char *p = "", *q = "";
+ if (spec->src)
+ p = skip_prefix(spec->src, "refs/heads/");
+ if (spec->dst)
+ q = skip_prefix(spec->dst, "refs/heads/");
printf(" %s%s%s%s", spec->force ? "+" : "",
- skip_prefix(spec->src, "refs/heads/"),
+ p ? p : spec->src,
spec->dst ? ":" : "",
- skip_prefix(spec->dst, "refs/heads/"));
+ q ? q : spec->dst);
}
printf("\n");
}
diff --git a/git-compat-util.h b/git-compat-util.h
index 6f94a81..31edc98 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -127,6 +127,12 @@ extern void set_warn_routine(void (*routine)(const char *warn, va_list params));
extern int prefixcmp(const char *str, const char *prefix);
+static inline const char *skip_prefix(const char *str, const char *prefix)
+{
+ size_t len = strlen(prefix);
+ return strncmp(str, prefix, len) ? NULL : str + len;
+}
+
#ifdef NO_MMAP
#ifndef PROT_READ
diff --git a/parse-options.c b/parse-options.c
index b8bde2b..bbc3ca4 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -22,12 +22,6 @@ static inline const char *get_arg(struct optparse_t *p)
return *++p->argv;
}
-static inline const char *skip_prefix(const char *str, const char *prefix)
-{
- size_t len = strlen(prefix);
- return strncmp(str, prefix, len) ? NULL : str + len;
-}
-
static int opterror(const struct option *opt, const char *reason, int flags)
{
if (flags & OPT_SHORT)
--
1.5.6
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox