Git development
 help / color / mirror / Atom feed
* Re: svn versus git
From: Andy Parkins @ 2006-12-14  9:19 UTC (permalink / raw)
  To: git
In-Reply-To: <7vfybjbbsx.fsf@assigned-by-dhcp.cox.net>

On Wednesday 2006 December 13 23:45, Junio C Hamano wrote:

> ls-tree is not Porcelain and has right to expose the internals

Of course; but there is no porcelain to do that operation.

> by default.  "git ls-tree --name-only" could be aliased to give
> "git ls" if you wanted to, but I wonder how often you would want
> to run:
>
> 	svn list -r538
>
> and for what purpose?

I've never done it.  However, the command is there in subversion, so I was 
comparing git's implementation of that command.  I wouldn't completely write 
it off though.  It doesn't seem unreasonable to want to see what files were 
in an old revision.

> I often find myself doing
> 	git diff -r --name-status v1.3.0 HEAD

I can live with that as an acceptable alternative to "svn list"; however, as 
usual, how does my imaginary ex-svn user find out about that?  man git-diff 
isn't the first place /I'd/ go; and even if you do, you won't find the "-r" 
or "--name-status" options; you have to go to git-diff-files, git-diff-index 
or git-diff-tree - and you're meant to guess which is the right one.

Bear in mind that my current theme isn't "can git do...?" it's "how does a 
user know that git can do...?"

> What do people use "svn list -r538" for and how often?  In other
> words, when does it become necessary to get the full list of
> paths in an arbitrary revision?

Me: I don't do it often.  It's not something I'd lose sleep over if git 
doesn't have an easy way of doing it.  However, it was in the output 
of "svn --help"; so I included it.

Andy
-- 
Dr Andy Parkins, M Eng (hons), MIEE

^ permalink raw reply

* [PATCH] git-reset [--mixed] <tree> [--] <paths>...
From: Junio C Hamano @ 2006-12-14  9:24 UTC (permalink / raw)
  To: git

Sometimes it is asked on the list how to revert selected path in
the index from a tree, most often HEAD, without affecting the
files in the working tree.  A similar operation that also
affects the working tree files has been available in the form of
"git checkout <tree> -- <paths>...".

By definition --soft would never affect either the index nor the
working tree files, and --hard is the way to make the working
tree files as close to pristine, so this new option is available
only for the default --mixed case.

Signed-off-by: Junio C Hamano <junkio@cox.net>
---

 * I haven't looked at Documentation/git-reset.txt recently.  It
   most likely needs not just addition to describe this new
   format, but more a heavier rewrite similar to what we made to
   git-commit documentation recently.

 git-reset.sh |   68 +++++++++++++++++++++++++++++++++++++++------------------
 1 files changed, 46 insertions(+), 22 deletions(-)

diff --git a/git-reset.sh b/git-reset.sh
index 03d2c3b..e95c252 100755
--- a/git-reset.sh
+++ b/git-reset.sh
@@ -1,35 +1,59 @@
 #!/bin/sh
-
-USAGE='[--mixed | --soft | --hard]  [<commit-ish>]'
+#
+# Copyright (c) 2005, 2006 Linus Torvalds and Junio C Hamano
+#
+USAGE='[--mixed | --soft | --hard]  [<commit-ish>] [ [--] <paths>...]'
 SUBDIRECTORY_OK=Yes
 . git-sh-setup
 
+update= rev= reset_type=--mixed
+
+while case $# in 0) break ;; esac
+do
+	case "$1" in
+	--mixed | --soft | --hard)
+		reset_type="$1"
+		;;
+	--)
+		break
+		;;
+	-*)
+		usage
+		;;
+	*)
+		rev=$(git-rev-parse --verify "$1") || exit
+		shift
+		break
+		;;
+	esac
+	shift
+done
+
+: ${rev=HEAD}
+rev=$(git-rev-parse --verify $rev^0) || exit
+
+# Skip -- in "git reset HEAD -- foo" and "git reset -- foo".
+case "$1" in --) shift ;; esac
+
+# git reset --mixed tree [--] paths... can be used to
+# load chosen paths from the tree into the index without
+# affecting the working tree nor HEAD.
+if test $# != 0
+then
+	test "$reset_type" == "--mixed" ||
+		die "Cannot do partial $reset_type reset."
+	git ls-tree -r --full-name $rev -- "$@" |
+	git update-index --add --index-info || exit
+	git update-index --refresh
+	exit
+fi
+
 TOP=$(git-rev-parse --show-cdup)
 if test ! -z "$TOP"
 then
 	cd "$TOP"
 fi
 
-update=
-reset_type=--mixed
-case "$1" in
---mixed | --soft | --hard)
-	reset_type="$1"
-	shift
-	;;
--*)
-        usage ;;
-esac
-
-case $# in
-0) rev=HEAD ;;
-1) rev=$(git-rev-parse --verify "$1") || exit ;;
-*) usage ;;
-esac
-rev=$(git-rev-parse --verify $rev^0) || exit
-
-# We need to remember the set of paths that _could_ be left
-# behind before a hard reset, so that we can remove them.
 if test "$reset_type" = "--hard"
 then
 	update=-u
-- 
1.4.4.2.g86bd


^ permalink raw reply related

* Re: What's in git.git (stable)
From: Andy Parkins @ 2006-12-14  9:27 UTC (permalink / raw)
  To: git
In-Reply-To: <elpvro$rvj$1@sea.gmane.org>

On Wednesday 2006 December 13 22:48, Jakub Narebski wrote:

> Nice list, although I'd rather add extra output only if command is used
> with -v/--verbose (or -V/--verbose) option; if not, then add -q/--quiet
> (or -s/--silent) option to be used in scripts. I'm partial to --verbose

I'd rather have the scripts requiring "--quiet"; because otherwise it's 
another switch for a newbie to guess at.  However, I don't think that 
switches is the answer.  Output for these porcelain-level commands is not 
structured enough to be used in scripts anyway (e.g. git-pull), but what it 
does output is a confusing lump.

> solution, as advanced users are not interested in any output; they know
> the commands, and want them to be fast. C.f GNU tar: it outputs something
> only with -v/--verbose option.

tar is doing a considerably less complicated sequence of operations than many 
of git's commands, so I don't think that's a fair comparison.

Also; I don't think "experts" should care about the extra output - I can't 
imagine that an extra few lines of text is going to slow git down.  Further, 
I think the problem in most cases is that git outputs _too much_.  Also, I'm 
not imagining that "git-add ." would list every file that it added - who is 
that going to help?  It should say "added X files to index" or similar.  You 
surely can't be arguing that that slows down your expert workflow?

I believe that a good set of output will be useful to both newbies and experts 
alike.  The idea that experts don't like to know what's going on is simply 
not true.  The idea that newbies want to see every file listed and every 
operation described is simply not true.



Andy
-- 
Dr Andy Parkins, M Eng (hons), MIEE

^ permalink raw reply

* Re: What's in git.git (stable)
From: Shawn Pearce @ 2006-12-14  9:36 UTC (permalink / raw)
  To: Andy Parkins; +Cc: git
In-Reply-To: <200612140927.27259.andyparkins@gmail.com>

Andy Parkins <andyparkins@gmail.com> wrote:
> I think the problem in most cases is that git outputs _too much_.  Also, I'm 
> not imagining that "git-add ." would list every file that it added - who is 
> that going to help?  It should say "added X files to index" or similar.  You 
> surely can't be arguing that that slows down your expert workflow?

git-commit-tree's "committing initial tree" and git-init-db's
"defaulting to local storage area" are both probably too verbose
and should just get removed.

The progress meters in git-pack-objects that you see during clone,
repack, fetch and push at least keep the user amused.  I do read
the output of repack every so often, but in general I don't care
about the output of clone, fetch or push - all I care about is
that my objects got to the remote system and were accepted, or not.
Which means that at least for me the output could be reduced down
to just the bandwidth transfer meter, for really slow links.

But I'm not sure that git-add should output anything.  Last I checked
the 'mv' command in Linux doesn't say "Move 5 files" when I move 5
files into a directory.  Likewise I don't think that knowing that
6781 files were added is useful, what if it should have really been
6782 files?  I'm unlikely to know, care, or realize it.

Your niggle list (is that what you called it) has been useful
fodder for discussion.  I'm glad you took the time to write it up,
and to argue it so well on the list.  There's a number of items on
it that I'd like to see happen too; enough that I may code some of
them if nobody beats me to it.

-- 

^ permalink raw reply

* Re: svn versus git
From: Junio C Hamano @ 2006-12-14  9:44 UTC (permalink / raw)
  To: Andy Parkins; +Cc: git
In-Reply-To: <200612140908.36952.andyparkins@gmail.com>

Andy Parkins <andyparkins@gmail.com> writes:

> On Wednesday 2006 December 13 22:56, Shawn Pearce wrote:
>
>>   git cat-file -p $REV:$file
>>
>> not sure how much easier it gets than that.  Load in the bash
>> completion from contrib/completion and you can even tab complete
>> the $file part.
>
> Yes.  I was a little unfair on that one; I forgot about the REV:file syntax.  
> However, it's still not simple for a new user; I think I'd say "draw" if 
> the "-p" weren't a requirement.

I would say pretending as if cat-file is a Porcelain is the
unfair part.

> $ git-ls-tree v1.0.0
> 100644 blob 906e98492080d2fde9467a9970fc92d7a8cfeaf8    Makefile
>
> I'm a newbie:  what's that number at the front?  What's a blob?  What's that 
> great big number - I've only seen commit hashes that look like that, and that 
> isn't one.  Definitely not friendly.

Again, mistaking ls-tree as if it was a Porcelain is the true
cause of the newbie confusion.

> It could probably be fixed by making git-ls-files capable of understanding 
> tree-ish.

I think that's a wrong way to go about.  The primary purpose of
ls-files is to read the index and show information around it;
ls-tree is about reading one tree and show information around
it.  They are both plumbing and meant to be used by scripts when
they want to inspect the index or a tree respectively.

If a Porcelain level "ls" is needed (and I am doubtful about
usefulness of "svn list -r538" like command), that is the
command you would want to teach about using ls-files and ls-tree
depending on what the end users want in their workflow.

^ permalink raw reply

* Re: What's in git.git (stable)
From: Andy Parkins @ 2006-12-14  9:59 UTC (permalink / raw)
  To: git
In-Reply-To: <7vk60vbcfz.fsf@assigned-by-dhcp.cox.net>

On Wednesday 2006 December 13 23:31, Junio C Hamano wrote:

> I am moderately against making a command verbosely report when

I'm not sure "verbose" is the word for one extra line of output:

$ git commit
Revision XXXXXXXXXXXXXXXXXX successfully added.

I'd actually argue that git-commit is a particular problem because it's too 
fast.  You quit editing your commit message and bang, you're back at the 
command line.  Then you run git-log to make sure it really was committed.

> it did exactly what it was told to do, _unless_ the command is
> expected to take longer than other commands in git suite, or it
> is something the user rarely runs.

In the specific case of commit I really think the hash that was added needs to 
be printed.  I often do a series of git-commits on separate files; to find 
out the hash of one of those recent commits I then hop over to qgit to look.  
If it were right there on my terminal I wouldn't need to have qgit open all 
the time.

> >  * git-branch is not verbose enough when creating a new
> The same comment applies here.

Right back at you.  "what it was told to do", is not a clear cut thing.  Bear 
in mind that users make mistakes (I certainly do), so what I told it to do 
was not necessarily what I wanted it to do.  With no output to tell me what 
actually happened, it makes it harder to go back and see what you did wrong.

> However, perhaps you could make lack of "[user] expert = true"
> in ~/.gitconfig to trigger more verbose messages that say "yes
> sir I did what I was told to do".

I've always thought that programs that needed an expert/beginner split were 
badly designed.

I'm not sure you're characterising the messages correctly with "yes
sir I did what I was told to do".  That sort of output would truly be useless.  
However, going back to my git-commit example, I didn't say "commit and give 
this the hash XXXXXXXX", I said "commit".  git makes up the hash for me, and 
so should really tell me that hash.

> Not interested in implementing that myself at all, though.

I've gotten a far more positive response than I'd expected, so it doesn't 
surprise me.

> >  Tell them if they
> >  made a branch as well, which branch they are now on.
>
> I think you are talking about "checkout -b" not commit here;
> this might be a borderline (branch creation is less often done
> and it might warrant assuring feedback), but I think it still
> falls into the "doing exactly what it was told to do" category.

You're right, I was.  The reason I think feedback is useful is because of the 
two ways of making a new branch:
 - git-branch XYZ
   This makes a new branch but DOESN'T leave me on XYZ
 - git-commit -b XYZ
   This makes a new branch and switches to XYZ
I can't tell you the number of times I get this wrong.  It's not because I 
don't know if I stop to think, it's because I'm thinking about the project, 
not the VCS.

> No.  It either says patch is corrupt, or a hunk at this line
> does not apply.  I do not see what more would you would want to
> ask it to say.

I've been building a repository that contains every kernel release since 
v1.0.0; I did it by downloading every patch and "git-apply"ing them one at a 
time.  Along the way, I had a few occasions where the patch didn't apply.  I 
would get the "hunk didn't apply" message. (e.g. v1.1/patch54.bz2 if you're 
interested)

Now - it /should/ apply, this is a published patch; I investigated each one, 
and it was always down to a whitespace problem.  The current version didn't 
have the same whitespace as the patch was expecting; often part of a much 
larger patch which mostly applied.  git-apply could have told me...

While applying hunk #17, the following update would not apply to the file
this/that/theother.c
-#endif
+#endif

Instead I had to git-checkout HEAD; bzcat patch | git-apply --reject; 
find . -name "*.rej"; vim; git update-index; blah, blah blah.

> As long as your solution does not accidentally lose local,
> unrelated changes, changing "git-rebase --skip" to do the needed
> clean-up itself for the user would be Ok (I think we would want

Of course; never discarding data always takes precedence.

> While I agree the users need to be taught about 'prune', I do
> think immediately after running the above commands is exactly
> the wrong point to run 'prune'.  'prune' should not be run while
> you are busily munging the tip of the branch with rebase and
> reset to come up with something that you can call "oh, I am done
> with this series for now."  Otherwise even lost-found would not
> be able to help you.

Absolutely; I wasn't suggesting that the message should say "now run 
git-prune"; otherwise we might as well run git-prune ourselves.  I don't 
really know that the solution is; but I do think we need one.

> In general the principle ought to be not to say anything if the
> command does exactly what it was told to do successfully, unless
> the operation is expected to take longer than other normal
> commands in the git suite, or something that is rarely used.

git is its own worst enemy here I think.  I still have doubts that something 
actually happened when I run commands because they return so quickly.

> Perhaps under "[user] expert" control.

I think the problem with that is going to be that there will be disagreement 
about which commands should output what in which mode.  "I like git-commit to 
tell me what it committed, but don't want git-add to list files" sorts of 
thing.



Andy

-- 
Dr Andy Parkins, M Eng (hons), MIEE

^ permalink raw reply

* Re: [PATCH] git-reset [--mixed] <tree> [--] <paths>...
From: Junio C Hamano @ 2006-12-14 10:02 UTC (permalink / raw)
  To: git
In-Reply-To: <7vwt4u96e8.fsf@assigned-by-dhcp.cox.net>

Junio C Hamano <junkio@cox.net> writes:

> Sometimes it is asked on the list how to revert selected path in
> the index from a tree, most often HEAD, without affecting the
> files in the working tree...

The patch depends on another one that allows the command to work
from a subdirectory (and also has one bug).  Updated one will
appear in 'next'.

^ permalink raw reply

* Re: What's in git.git (stable)
From: Andy Parkins @ 2006-12-14 10:03 UTC (permalink / raw)
  To: git
In-Reply-To: <20061214093637.GC1747@spearce.org>

On Thursday 2006 December 14 09:36, Shawn Pearce wrote:

> But I'm not sure that git-add should output anything.  Last I checked
> the 'mv' command in Linux doesn't say "Move 5 files" when I move 5
> files into a directory.  Likewise I don't think that knowing that
> 6781 files were added is useful, what if it should have really been
> 6782 files?  I'm unlikely to know, care, or realize it.

That's a very particular example you've picked out there.  Of course the user 
won't know if it should be 6781 or 6782; they might know if it should have 
been 2 or 10 though; 0 or 100.  In your example, output like "about six and a 
half thousand", would probably be perfectly useful, but why not just output 
the number?

> Your niggle list (is that what you called it) has been useful
> fodder for discussion.  I'm glad you took the time to write it up,
> and to argue it so well on the list.  There's a number of items on
> it that I'd like to see happen too; enough that I may code some of
> them if nobody beats me to it.

I'm glad it was useful.  I never know how many disclaimers to put on these 
things.  I always feel that every message I write should begin with "I love 
git and use it every day, so please don't take this the wrong way, but..."



Andy
-- 
Dr Andy Parkins, M Eng (hons), MIEE

^ permalink raw reply

* [PATCH 1/1] Bypass expensive content comparsion during rename detection.
From: Shawn O. Pearce @ 2006-12-14 10:07 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

When comparing file contents during the second loop through a rename
detection attempt we can skip the expensive byte-by-byte comparsion
if both source and destination files have valid SHA1 values.  This
improves performance by avoiding either an expensive open/mmap to
read the working tree copy, or an expensive inflate of a blob object.

Unfortunately we still have to at least initialize the sizes of the
source and destination files even if the SHA1 values don't match.
Failing to initialize the sizes causes a number of test cases to fail
and start reporting different copy/rename behavior than was expected.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
 diffcore-rename.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/diffcore-rename.c b/diffcore-rename.c
index 57a74b6..91fa2be 100644
--- a/diffcore-rename.c
+++ b/diffcore-rename.c
@@ -109,6 +109,8 @@ static int is_exact_match(struct diff_filespec *src,
 		return 0;
 	if (src->size != dst->size)
 		return 0;
+	if (src->sha1_valid && dst->sha1_valid)
+	    return !hashcmp(src->sha1, dst->sha1);
 	if (diff_populate_filespec(src, 0) || diff_populate_filespec(dst, 0))
 		return 0;
 	if (src->size == dst->size &&
-- 

^ permalink raw reply related

* Re: What's in git.git (stable)
From: Andy Parkins @ 2006-12-14 10:21 UTC (permalink / raw)
  To: git
In-Reply-To: <Pine.LNX.4.63.0612140116430.3635@wbgn013.biozentrum.uni-wuerzburg.de>

On Thursday 2006 December 14 00:22, Johannes Schindelin wrote:

> >  * git-revert should be called git-invert.  It doesn't remove a change
> >    from history, it simply applies another commit that does the
> >    opposite of whatever commit you are "revert"ing.  That's an inversion.
>
> No. An inversion is the _opposite_. Not an undo.

That's what I'm saying, we are applying the opposite of the given commit - 
that commit is being inverted and applied again.  It most certainly isn't an 
undo, because the original commit still exists.  It's not a reversion 
because "reversion" is to regress to a previous time or state.  In that sense 
git-revert is not doing what it says on the tin.  A revert would be to remove 
all the revisions from now until the specified commit - i.e. what git-reset 
now does.

(Note: I don't think git-reset should be renamed, as it's possible to use 
git-reset to move a branch forward as well as backward).

> Besides, The fact that revert _adds_ to history is a nice way to
> document that you reverted that change. And you can even explain in the
> commit message, why you did it.

I'm not disputing that the /operation/ is useful, I'm arguing that it is 
incorrectly named.

> IMHO it is better for a newbie to see that _something_ is happening. A

I'm not arguing that we should show nothing; I'm arguing that the something we 
do show should be more clear than what is now shown.  The choice is 
therefore "show something confusing" or "show something clear".

> newbie cannot, and does not want to, understand exactly what is going on.

"newbie" doesn't mean "idiot".  Everybody wants to understand what is going 
on.

> So, think of it as our response to Windows' non-progress-bar: when you
> start up Windows, there is a progress-bar, except that it does not show
> progress, but a Knight Rider like movement, only indicating that it does
> something.

Given the choice between nothing and a non-progress "doing something" bar, I 
would of course pick the "doing something" bar.  However, given the choice 
between a "doing something" bar and a progress bar, I'd rather have the 
progress bar.


Andy
-- 
Dr Andy Parkins, M Eng (hons), MIEE

^ permalink raw reply

* Re: What's in git.git (stable)
From: Junio C Hamano @ 2006-12-14 10:21 UTC (permalink / raw)
  To: Andy Parkins; +Cc: git
In-Reply-To: <200612140959.19209.andyparkins@gmail.com>

Andy Parkins <andyparkins@gmail.com> writes:

> $ git commit
> Revision XXXXXXXXXXXXXXXXXX successfully added.
>
> I'd actually argue that git-commit is a particular problem because it's too 
> fast.  You quit editing your commit message and bang, you're back at the 
> command line.  Then you run git-log to make sure it really was committed.

You keep repeating that you want to know the object name of the
newly created commit.  I would very strongly agree with you that
it would be a fatal UI bug of git-commit if that information
were vital for the end user after making each commit.

But you never communicate with your own git repository using the
SHA-1 object names when talking about commits you made recently
(you would have the SHA-1 output from your updated version of
'git commit' command on the screen or in your scrollbuffer for
them -- you would need to refer to commits older than what your
scrollbuffer has in different way anyway).  Git gives branch~<n>
notation, and commands like "git log --pretty=short" and friends
would show them which you can easily cut&paste.  When people
talk about object names on the mailing list, they do so by
asking "git log" and friends to find them out -- it is pretty
much "on demand" type of thing and I do not think continually
mentioning SHA-1 object names buys us anything.

In other words, the following transcript would be possible but
not realistic:

	$ git commit
        Revision deadbeef0000 created.
        : now what did I do?
        $ git show deadbeef0000
        : oops, that is wrong
        $ git reset --hard deadbeef0000^

So I do not think "git commit" is a valid example.  I also agree
with Shawn that "git add" that says 6781 files were added is
pointless.

>> However, perhaps you could make lack of "[user] expert = true"
>> in ~/.gitconfig to trigger more verbose messages that say "yes
>> sir I did what I was told to do".
>
> I've always thought that programs that needed an expert/beginner split were 
> badly designed.

There probably is a truth in that.  Let's not add verbosity
unnecessarily.

I agree with you that making some commands with progress
indication less chatty would be a good clean-up.

^ permalink raw reply

* Re: git-show, was Re: What's in git.git (stable)
From: Johannes Schindelin @ 2006-12-14 10:25 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Nicolas Pitre, git
In-Reply-To: <7vbqm6anjz.fsf@assigned-by-dhcp.cox.net>

Hi,

On Thu, 14 Dec 2006, Junio C Hamano wrote:

> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> 
> > Hi,
> >
> > On Wed, 13 Dec 2006, Junio C Hamano wrote:
> >
> >> One minor issue we may need to decide is what to do when show is
> >> given a tag object.  Personally I think the current behaviour of
> >> dereferencing it to commit is fine (people who want to see the
> >> tag can always do 'git-verify-tag -v').
> >
> > How about adding the command line option "--tag" to git-show, which makes 
> > it only show that tag. I'd also vote for a "--verbose|-v" flag to show the 
> > contents of the tag _before_ showing the referenced object.
> 
> Sounds sensible.  Please make it so.

Actually, I rethought it. A tag _without_ what it tags makes no sense. See 
my upcoming patch. And git-show really is as Porcelain as it gets, so it 
should Do What I Mean.

Ciao,
Dscho

^ permalink raw reply

* [PATCH] git-show: grok blobs, trees and tags, too
From: Johannes Schindelin @ 2006-12-14 10:31 UTC (permalink / raw)
  To: git, junkio


Since git-show is pure Porcelain, it is the ideal candidate to
pretty print other things than commits, too.

Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>

---

 Documentation/git-show.txt |   40 ++++++++++++++++++---
 builtin-log.c              |   82 +++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 114 insertions(+), 8 deletions(-)

diff --git a/Documentation/git-show.txt b/Documentation/git-show.txt
index 4c880a8..1d9d781 100644
--- a/Documentation/git-show.txt
+++ b/Documentation/git-show.txt
@@ -3,20 +3,27 @@ git-show(1)
 
 NAME
 ----
-git-show - Show one commit with difference it introduces
+git-show - Show blobs, trees, tags and commits with difference they introduce
 
 
 SYNOPSIS
 --------
-'git-show' <option>...
+'git-show' [options] <object>...
 
 DESCRIPTION
 -----------
-Shows commit log and textual diff for a single commit.  The
-command internally invokes 'git-rev-list' piped to
-'git-diff-tree', and takes command line options for both of
-these commands. It also presents the merge commit in a special
-format as produced by 'git-diff-tree --cc'.
+Shows one or more objects.
+
+For commits it shows the log message and textual diff. It also
+presents the merge commit in a special format as produced by
+'git-diff-tree --cc'.
+
+For tags, it shows the tag message and the referenced objects.
+
+For trees, it shows the names (equivalent to gitlink:git-ls-tree[1]
+with \--name-only).
+
+For plain blobs, it shows the plain contents.
 
 This manual page describes only the most frequently used options.
 
@@ -28,6 +35,25 @@ OPTIONS
 
 include::pretty-formats.txt[]
 
+
+EXAMPLES
+--------
+
+git show v1.0.0::
+	Shows the tag `v1.0.0`.
+
+git show v1.0.0^{tree}::
+	Shows the tree pointed to by the tag `v1.0.0`.
+
+git show next~10:Documentation/README
+	Shows the contents of the file `Documentation/README` as
+	they were current in the 10th last commit of the branch
+	`next`.
+
+git show master:Makefile master:t/Makefile
+	Concatenates the contents of said Makefiles in the head
+	of the branch `master`.
+
 Author
 ------
 Written by Linus Torvalds <torvalds@osdl.org> and
diff --git a/builtin-log.c b/builtin-log.c
index 6821a08..17014f7 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -10,6 +10,7 @@
 #include "revision.h"
 #include "log-tree.h"
 #include "builtin.h"
+#include "tag.h"
 #include <time.h>
 #include <sys/time.h>
 
@@ -71,9 +72,43 @@ int cmd_whatchanged(int argc, const char **argv, const char *prefix)
 	return cmd_log_walk(&rev);
 }
 
+static int show_object(const unsigned char *sha1, int suppress_header)
+{
+	unsigned long size;
+	char type[20];
+	char *buf = read_sha1_file(sha1, type, &size);
+	int offset = 0;
+
+	if (!buf)
+		return error("Could not read object %s", sha1_to_hex(sha1));
+
+	if (suppress_header)
+		while (offset < size && buf[offset++] != '\n') {
+			int new_offset = offset;
+			while (new_offset < size && buf[new_offset++] != '\n')
+				; /* do nothing */
+			offset = new_offset;
+		}
+
+	if (offset < size)
+		fwrite(buf + offset, size - offset, 1, stdout);
+	free(buf);
+	return 0;
+}
+
+static int show_tree_object(const unsigned char *sha1,
+		const char *base, int baselen,
+		const char *pathname, unsigned mode, int stage)
+{
+	printf("%s%s\n", pathname, S_ISDIR(mode) ? "/" : "");
+	return 0;
+}
+
 int cmd_show(int argc, const char **argv, const char *prefix)
 {
 	struct rev_info rev;
+	struct object_array_entry *objects;
+	int i, count, ret = 0;
 
 	git_config(git_log_config);
 	init_revisions(&rev, prefix);
@@ -85,7 +120,52 @@ int cmd_show(int argc, const char **argv, const char *prefix)
 	rev.ignore_merges = 0;
 	rev.no_walk = 1;
 	cmd_log_init(argc, argv, prefix, &rev);
-	return cmd_log_walk(&rev);
+
+	count = rev.pending.nr;
+	objects = rev.pending.objects;
+	for (i = 0; i < count && !ret; i++) {
+		struct object *o = objects[i].item;
+		const char *name = objects[i].name;
+		switch (o->type) {
+		case OBJ_BLOB:
+			ret = show_object(o->sha1, 0);
+			break;
+		case OBJ_TAG: {
+			struct tag *t = (struct tag *)o;
+
+			printf("%stag %s%s\n\n",
+					diff_get_color(rev.diffopt.color_diff,
+						DIFF_COMMIT),
+					t->tag,
+					diff_get_color(rev.diffopt.color_diff,
+						DIFF_RESET));
+			ret = show_object(o->sha1, 1);
+			objects[i].item = (struct object *)t->tagged;
+			i--;
+			break;
+		}
+		case OBJ_TREE:
+			printf("%stree %s%s\n\n",
+					diff_get_color(rev.diffopt.color_diff,
+						DIFF_COMMIT),
+					name,
+					diff_get_color(rev.diffopt.color_diff,
+						DIFF_RESET));
+			read_tree_recursive((struct tree *)o, "", 0, 0, NULL,
+					show_tree_object);
+			break;
+		case OBJ_COMMIT:
+			rev.pending.nr = rev.pending.alloc = 0;
+			rev.pending.objects = NULL;
+			add_object_array(o, name, &rev.pending);
+			ret = cmd_log_walk(&rev);
+			break;
+		default:
+			ret = error("Unknown type: %d", o->type);
+		}
+	}
+	free(objects);
+	return ret;
 }
 

^ permalink raw reply related

* Re: changing log entries
From: Andy Parkins @ 2006-12-14 10:37 UTC (permalink / raw)
  To: git
In-Reply-To: <1166051281.1808.1.camel@jcm.boston.redhat.com>

On Wednesday 2006 December 13 23:08, Jon Masters wrote:

> Anyway, now I would like to change an existing log entry to make it a
> bit cleaner (read: add a first line that's under 80 characters). What's
> the best way to change an existing log entry for a commit?

If it's HEAD you want to change:
 git-commit --amend

If it's not, it's a bit harder.  You could pull each commit out as a patch and 
apply them again later after a git-reset.  However, git has a tool for 
automating a lot of that:  git-rebase.  man git-rebase has some excellent 
examples.

 * -- A -- B -- C (master)

Let's say you want to edit A; make a new branch at A:

$ git branch temp-edit-branch master^^
 
 * -- A (temp-edit-branch)
       \
        B -- C (master)

Edit A with git-commit --amend.  This makes a new A, A' that has the new 
commit message:

 * -- A' (temp-edit-branch)
  \
   A -- B -- C (master)

Then you switch to "master" and rebase master onto temp-edit-branch; you can 
then delete temp-edit-branch

$ git-checkout master
$ git-rebase temp-edit-branch
$ git branch -D temp-edit-branch

 * -- A' -- B' -- C' (master)
  \
   A -- B -- C

Note that A-B-C are now dangling commits; a git-prune would be needed to clean 
them out of the repository.

The important thing to realise is that you can never really edit a commit.  
The best you can do is reapply it.  In this example, the fact that B' makes 
the same change as B is irrelevant - they are two separate commits.

Note: this is only workable if you haven't pushed this branch to another 
repository.  The other repository would retain the original A--B--C branch 
and you will get "won't fast forward" errors if you try to push the 
new "A'--B'--C'" branch.


Andy
-- 
Dr Andy Parkins, M Eng (hons), MIEE

^ permalink raw reply

* Re: [PATCH] git-show: grok blobs, trees and tags, too
From: Shawn Pearce @ 2006-12-14 10:37 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: git, junkio
In-Reply-To: <Pine.LNX.4.63.0612141129320.3635@wbgn013.biozentrum.uni-wuerzburg.de>

Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
>..

Nice!  I like this.

> +git show master:Makefile master:t/Makefile
> +	Concatenates the contents of said Makefiles in the head
> +	of the branch `master`.
> +

Uh, isn't that what cat does?  Shouldn't this be "git cat"?  :-)

Nevermind.  :)

-- 

^ permalink raw reply

* [PATCH] INSTALL: no need to have GNU diff installed
From: Johannes Schindelin @ 2006-12-14 10:40 UTC (permalink / raw)
  To: git, junkio


Since a long time, we have inbuilt diff generation.

Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
---
 INSTALL |   10 ----------
 1 files changed, 0 insertions(+), 10 deletions(-)

diff --git a/INSTALL b/INSTALL
index b5dd9f0..e7aea60 100644
--- a/INSTALL
+++ b/INSTALL
@@ -72,16 +72,6 @@ Issues of note:
 	- expat library; git-http-push uses it for remote lock
 	  management over DAV.  Similar to "curl" above, this is optional.
 
-	- "GNU diff" to generate patches.  Of course, you don't _have_ to
-	  generate patches if you don't want to, but let's face it, you'll
-	  be wanting to. Or why did you get git in the first place?
-
-	  Non-GNU versions of the diff/patch programs don't generally support
-	  the unified patch format (which is the one git uses), so you
-	  really do want to get the GNU one.  Trust me, you will want to
-	  do that even if it wasn't for git.  There's no point in living
-	  in the dark ages any more. 
-
         - "wish", the Tcl/Tk windowing shell is used in gitk to show the
           history graphically
 
-- 
1.4.4.2.ga1b439-dirty

^ permalink raw reply related

* Re: svn versus git
From: Andy Parkins @ 2006-12-14 10:42 UTC (permalink / raw)
  To: git
In-Reply-To: <7vodq695ha.fsf@assigned-by-dhcp.cox.net>

On Thursday 2006 December 14 09:44, Junio C Hamano wrote:

> I would say pretending as if cat-file is a Porcelain is the
> unfair part.

I had to; there is no other equivalent of "svn cat" in git.

> Again, mistaking ls-tree as if it was a Porcelain is the true
> cause of the newbie confusion.

Again, there is no other equivalent of "svn list" in git.

> If a Porcelain level "ls" is needed (and I am doubtful about
> usefulness of "svn list -r538" like command), that is the

Me too.  I was in no way advocating that git should try to be SVN (shudder).  
As I was comparing though, I had to pick git commands that did at least what 
SVN could do.

> command you would want to teach about using ls-files and ls-tree
> depending on what the end users want in their workflow.

Personally, I think qgit fills an awfully big hole in svn that makes them all 
irrelevant.  qgit is a much better repository browsing tool than "svn list" 
is.



Andy
-- 
Dr Andy Parkins, M Eng (hons), MIEE

^ permalink raw reply

* Re: [PATCH] git-show: grok blobs, trees and tags, too
From: Johannes Schindelin @ 2006-12-14 10:47 UTC (permalink / raw)
  To: Shawn Pearce; +Cc: git, junkio
In-Reply-To: <20061214103741.GD1747@spearce.org>

Hi,

On Thu, 14 Dec 2006, Shawn Pearce wrote:

> Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> 
> > +git show master:Makefile master:t/Makefile
> > +	Concatenates the contents of said Makefiles in the head
> > +	of the branch `master`.
> > +
> 
> Uh, isn't that what cat does?  Shouldn't this be "git cat"?  :-)

Shhh! The dogs are sleeping!

Ciao,
Dscho

^ permalink raw reply

* Re: [PATCH] git-reset [--mixed] <tree> [--] <paths>...
From: Peter Baumann @ 2006-12-14 10:47 UTC (permalink / raw)
  To: git
In-Reply-To: <7vwt4u96e8.fsf@assigned-by-dhcp.cox.net>

On 2006-12-14, Junio C Hamano <junkio@cox.net> wrote:
> Sometimes it is asked on the list how to revert selected path in
> the index from a tree, most often HEAD, without affecting the
> files in the working tree.  A similar operation that also
> affects the working tree files has been available in the form of
> "git checkout <tree> -- <paths>...".
>
> By definition --soft would never affect either the index nor the
> working tree files, and --hard is the way to make the working
> tree files as close to pristine, so this new option is available
> only for the default --mixed case.
>
> Signed-off-by: Junio C Hamano <junkio@cox.net>
> ---
>
>  * I haven't looked at Documentation/git-reset.txt recently.  It
>    most likely needs not just addition to describe this new
>    format, but more a heavier rewrite similar to what we made to
>    git-commit documentation recently.
>
>  git-reset.sh |   68 +++++++++++++++++++++++++++++++++++++++------------------
>  1 files changed, 46 insertions(+), 22 deletions(-)
>
> diff --git a/git-reset.sh b/git-reset.sh
> index 03d2c3b..e95c252 100755
> --- a/git-reset.sh
> +++ b/git-reset.sh
> @@ -1,35 +1,59 @@
>  #!/bin/sh
> -
> -USAGE='[--mixed | --soft | --hard]  [<commit-ish>]'
> +#
> +# Copyright (c) 2005, 2006 Linus Torvalds and Junio C Hamano
> +#
> +USAGE='[--mixed | --soft | --hard]  [<commit-ish>] [ [--] <paths>...]'
>  SUBDIRECTORY_OK=Yes
>  . git-sh-setup
>  
> +update= rev= reset_type=--mixed
> +
> +while case $# in 0) break ;; esac
> +do
> +	case "$1" in
> +	--mixed | --soft | --hard)
> +		reset_type="$1"
> +		;;
> +	--)
> +		break
> +		;;
> +	-*)
> +		usage
> +		;;
> +	*)
> +		rev=$(git-rev-parse --verify "$1") || exit
> +		shift
> +		break
> +		;;
> +	esac
> +	shift
> +done
> +
> +: ${rev=HEAD}
> +rev=$(git-rev-parse --verify $rev^0) || exit
> +
> +# Skip -- in "git reset HEAD -- foo" and "git reset -- foo".
> +case "$1" in --) shift ;; esac
> +
> +# git reset --mixed tree [--] paths... can be used to
> +# load chosen paths from the tree into the index without
> +# affecting the working tree nor HEAD.
> +if test $# != 0
> +then
> +	test "$reset_type" == "--mixed" ||
> +		die "Cannot do partial $reset_type reset."
> +	git ls-tree -r --full-name $rev -- "$@" |
> +	git update-index --add --index-info || exit
> +	git update-index --refresh
> +	exit
> +fi
> +

Why not make

	git-reset --hard <treeish> -- file

aquivalent to

	git-checkout <treeish> -- file

-Peter

PS:	Your patch didn't apply cleanly. And I couldn't find the blobs
	03d2c3b..e95c252 even after pulling (pu, next, master) in my
	git repository

^ permalink raw reply

* Re: [PATCH] git-show: grok blobs, trees and tags, too
From: Junio C Hamano @ 2006-12-14 10:50 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: git
In-Reply-To: <Pine.LNX.4.63.0612141129320.3635@wbgn013.biozentrum.uni-wuerzburg.de>

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

> +			ret = show_object(o->sha1, 1);
> +			objects[i].item = (struct object *)t->tagged;
> +			i--;
> +			break;

Good hack ;-).

^ permalink raw reply

* Re: What's in git.git (stable)
From: Johannes Schindelin @ 2006-12-14 10:51 UTC (permalink / raw)
  To: Andy Parkins; +Cc: git
In-Reply-To: <200612141021.12637.andyparkins@gmail.com>

Hi,

On Thu, 14 Dec 2006, Andy Parkins wrote:

> On Thursday 2006 December 14 00:22, Johannes Schindelin wrote:
> 
> > >  * git-revert should be called git-invert.  It doesn't remove a change
> > >    from history, it simply applies another commit that does the
> > >    opposite of whatever commit you are "revert"ing.  That's an inversion.
> >
> > No. An inversion is the _opposite_. Not an undo.
> 
> That's what I'm saying, we are applying the opposite of the given commit 
> - that commit is being inverted and applied again.

Ahh! I get what you are thinking. I was talking about reverting a change 
from the _content's viewpoint_. I _never_ want to revert history (I am no 
politician, you know?)

> > newbie cannot, and does not want to, understand exactly what is going 
> > on.
> 
> "newbie" doesn't mean "idiot".  Everybody wants to understand what is 
> going on.

I heartly disagree. I saw so many faces _begging_ me to just say _what_ to 
do, not _why_, and quickly, please.

> > So, think of it as our response to Windows' non-progress-bar: when you 
> > start up Windows, there is a progress-bar, except that it does not 
> > show progress, but a Knight Rider like movement, only indicating that 
> > it does something.
> 
> Given the choice between nothing and a non-progress "doing something" 
> bar, I would of course pick the "doing something" bar.  However, given 
> the choice between a "doing something" bar and a progress bar, I'd 
> rather have the progress bar.

If I have the choice between a "doing something" bar and a Windows 
Explorer "14 seconds left" bar showing the same message for two minutes, 
I'd rather have a Mars bar ;-)

Ciao,
Dscho

^ permalink raw reply

* Re: [PATCH 1/1] Bypass expensive content comparsion during rename detection.
From: Johannes Schindelin @ 2006-12-14 10:53 UTC (permalink / raw)
  To: Shawn O. Pearce; +Cc: Junio C Hamano, git
In-Reply-To: <20061214100746.GA31191@spearce.org>

Hi,

On Thu, 14 Dec 2006, Shawn O. Pearce wrote:

> When comparing file contents during the second loop through a rename 
> detection attempt we can skip the expensive byte-by-byte comparsion if 
> both source and destination files have valid SHA1 values.  This improves 
> performance by avoiding either an expensive open/mmap to read the 
> working tree copy, or an expensive inflate of a blob object.
> 
> Unfortunately we still have to at least initialize the sizes of the 
> source and destination files even if the SHA1 values don't match. 
> Failing to initialize the sizes causes a number of test cases to fail 
> and start reporting different copy/rename behavior than was expected.

It has a wrong feel to it when you say we have to check the sizes first. 
After all, we are heavily relying on the hashes being different, including 
the case when the sizes are different. So, the order of the checks should 
_not_ matter. I suspect that somewhere sha1_valid should be set to 0, but 
isn't.

Ciao,

^ permalink raw reply

* Re: [PATCH] git-show: grok blobs, trees and tags, too
From: Johannes Schindelin @ 2006-12-14 10:58 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7v3b7i92ez.fsf@assigned-by-dhcp.cox.net>

Hi,

On Thu, 14 Dec 2006, Junio C Hamano wrote:

> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> 
> > +			ret = show_object(o->sha1, 1);
> > +			objects[i].item = (struct object *)t->tagged;
> > +			i--;
> > +			break;
> 
> Good hack ;-).

Tail recursion ;-)

It has a nice side effect, too: the _name_ of the object is not changed, 
so if you show a tag which references a tree, you will see the name of the 
tag as if it were the name of the tree.

Ciao,
Dscho

^ permalink raw reply

* Re: [PATCH 1/1] Bypass expensive content comparsion during rename detection.
From: Shawn Pearce @ 2006-12-14 11:08 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.63.0612141151220.3635@wbgn013.biozentrum.uni-wuerzburg.de>

Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> On Thu, 14 Dec 2006, Shawn O. Pearce wrote:
> > Unfortunately we still have to at least initialize the sizes of the 
> > source and destination files even if the SHA1 values don't match. 
> > Failing to initialize the sizes causes a number of test cases to fail 
> > and start reporting different copy/rename behavior than was expected.
> 
> It has a wrong feel to it when you say we have to check the sizes first. 
> After all, we are heavily relying on the hashes being different, including 
> the case when the sizes are different. So, the order of the checks should 
> _not_ matter. I suspect that somewhere sha1_valid should be set to 0, but 
> isn't.

Yes.  :-)

I'll admit, I don't understand the diffcore rename code very well
so I'm treading around in code that I'm not used to.  I'm not sure
why the size member of diff_filespec needs to be initialized to get
rename and copy detection to work properly, but it apparently does.


My first version of the patch had the hash comparsion right after
we called diff_populate_filespec to get the size data.  But then
I realized that very often the sizes will be different and the
src->size != dst->size comparsion will tend to be true most of
the time, thus saving us a (relatively) expensive hash comparsion,
which we know must fail anyway if the sizes differed.

-- 

^ permalink raw reply

* Re: [PATCH 1/1] Bypass expensive content comparsion during rename detection.
From: Shawn Pearce @ 2006-12-14 11:13 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Junio C Hamano, git
In-Reply-To: <20061214110858.GE1747@spearce.org>

Shawn Pearce <spearce@spearce.org> wrote:
> I'll admit, I don't understand the diffcore rename code very well
> so I'm treading around in code that I'm not used to.  I'm not sure
> why the size member of diff_filespec needs to be initialized to get
> rename and copy detection to work properly, but it apparently does.

This chunk of code is probably a perfect example of why side-effects
can be so bad.  Its fast because the size information is loaded
once and reused later on; its horrible to maintain because you don't
realize that this simple predicate is actually doing something that
matters downstream even though it returned false!

-- 

^ permalink raw reply


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