Git development
 help / color / mirror / Atom feed
* Re: several quick questions
From: Keith Packard @ 2006-02-14 18:55 UTC (permalink / raw)
  To: Carl Worth; +Cc: keithp, Linus Torvalds, Nicolas Vilz 'niv', git
In-Reply-To: <87k6bxvmj6.wl%cworth@cworth.org>

[-- Attachment #1: Type: text/plain, Size: 579 bytes --]

On Tue, 2006-02-14 at 10:10 -0800, Carl Worth wrote:

> I don't know if it's the original poster's question or not, but an
> operation I don't see in the above is "put the working files into the
> state of a given revision".

I was using:

	 rm -r *
	 rm -f .cvsignore .gitignore
	 git-reset --hard <tag>

to get to a specific tag. Of course, I cloned the repository and did
this in a separate directory; I wanted to make sure nothing 'bad'
happened to my working directory.

Creating a fake branch seemed like a lot more bother.  
-- 
keith.packard@intel.com

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: several quick questions
From: Carl Worth @ 2006-02-14 18:44 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Nicolas Vilz 'niv', git
In-Reply-To: <87k6bxvmj6.wl%cworth@cworth.org>

[-- Attachment #1: Type: text/plain, Size: 590 bytes --]

On Tue, 14 Feb 2006 10:10:53 -0800, Carl Worth wrote:
> 
> Is there a more fundamental operation to "put the working files into
> the state of the index"? If that exists, then that combined with
> git-read-tree would give me what I wanted I think.

Oh, I'm blind. I didn't see git-checkout-index, (thanks Kenneth for
mentioning it elsewhere in the thread). So now I've at least got the
recipe I was after:

	git-read-tree <revision>
	git-update-index --replace
	git-checkout-index -a -f -u

And I think that would make for a dandy command to have in git. Any
suggestions for a name?

-Carl

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: several quick questions
From: Linus Torvalds @ 2006-02-14 18:34 UTC (permalink / raw)
  To: Carl Worth; +Cc: Nicolas Vilz 'niv', git
In-Reply-To: <87k6bxvmj6.wl%cworth@cworth.org>



On Tue, 14 Feb 2006, Carl Worth wrote:
> 
> I don't know if it's the original poster's question or not, but an
> operation I don't see in the above is "put the working files into the
> state of a given revision".

What a strange thing to ask for.

But you can do it several ways:

 - just use "git reset" to move around in history, possibly on a temporary 
   branch.

 - use "git checkout <rev> <filename>" to checkout a particular filename 
   of a particular version (it's a special case of "git checkout", which 
   is useful, but I personally think it's a bit confusing, so I wouldn't 
   mention it unless you asked)

 - use the core internal git functions, in particular

	git-read-tree -m -u <oldtree> <newtree>

   will switch from "oldtree" to "newtree" and update (-u) the working 
   tree.

> 2) Ensure that bogus-branch exists somewhere (don't care where), then
>    move it:
> 
> 	# Create the branch (if it doesn't exist)
> 	git checkout -b bogus-branch >& /dev/null
> 	# Switch to it (which doesn't happen above if it already existed)
> 	git checkout bogus-branch
> 	# Move the branch to the revision of interest
> 	git reset --hard <revision>

This is actually what I'd suggest you always do.

Why?

It's actually as efficient as anything else, and there's much less room 
for confusion. When you want to go back, you can just do a simple

	git checkout -f master

and there's no room for confusion. You've not lost sight of any old state, 
and your HEAD never differs from your checked-out copy, so all the normal 
commands work the way you'd expect them to.

		Linus

^ permalink raw reply

* Re: several quick questions
From: Linus Torvalds @ 2006-02-14 18:26 UTC (permalink / raw)
  To: Kenneth Johansson; +Cc: git
In-Reply-To: <pan.2006.02.14.17.47.53.126690@canit.se>



On Tue, 14 Feb 2006, Kenneth Johansson wrote:
> 
> What I ended up doing was going nee deep into the plumbing.
> 
> first doing cat on the tag in .git/refs/tags/ 
> taking the output as an argument to  "git-read-tree"
> followed by "git-update-index --replace" and "git-checkout-index -a -f -u"
> 
> I'm not sure that many people will understand that they want git-reset for
> this just reading the man pages.

Hey, but I bet you now as a result feel you really understand git, right? 

;)

You did it the old-fashioned way - the way real men did it back in June.

In general, doing "ls *.sh" in the git source tree shows you pretty much 
every command that you might ever want to use. Using the actual core git 
binaries directly is normally not all that useful, unless you want to do 
some strange shell pipeline to do statistics about different things in the 
tree.

		Linus

^ permalink raw reply

* Re: several quick questions
From: Kenneth Johansson @ 2006-02-14 18:21 UTC (permalink / raw)
  To: git
In-Reply-To: <43F21CB1.5010203@op5.se>

On Tue, 14 Feb 2006 19:08:49 +0100, Andreas Ericsson wrote:

> Kenneth Johansson wrote:
>> 
>> I'm not sure that many people will understand that they want git-reset for
>> this just reading the man pages.
>> 
> 
> Hence the tutorial.

It could be a little clearer what you would do in any other tool is
checkout a specifically tagged version. Perhaps adding a pointer from the
checkout man page to the reset command.

 

^ permalink raw reply

* Re: cg-clean, cg-status improvements
From: Pavel Roskin @ 2006-02-14 18:17 UTC (permalink / raw)
  To: Petr Baudis; +Cc: git
In-Reply-To: <20060214155356.GB9573@pasky.or.cz>

On Tue, 2006-02-14 at 16:53 +0100, Petr Baudis wrote:
>   I didn't plan to require git 1.2.0 with 0.17, so it would be better if
> you could do the workaround. But if the workaround means significant
> hassle, it's no biggie if git 1.2.0 will be required.

It turns out a proper workaround can only be implemented in cg-Xlib, not
in cg-clean.  It's a bit hairy for my taste (a bash guru could write it
better, I believe), but it's a compact blob of code that can be easily
removed at any time.

The patches have been sent by StGIT.

-- 
Regards,
Pavel Roskin

^ permalink raw reply

* Re: several quick questions
From: Carl Worth @ 2006-02-14 18:10 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Nicolas Vilz 'niv', git
In-Reply-To: <Pine.LNX.4.64.0602140845080.3691@g5.osdl.org>

[-- Attachment #1: Type: text/plain, Size: 2123 bytes --]

On Tue, 14 Feb 2006 09:05:16 -0800 (PST), Linus Torvalds wrote:
> 
> Both of these can be solved with "git reset".
...
>  - "git branch". This creates a new branch of development at an arbitrary 
>    point (that defaults to "current state").
> 
>  - "git checkout". This switches to another branch.
> 
>  - "git reset". This will reset the current branch state to something 
>    else.

Thanks for the summary.

I don't know if it's the original poster's question or not, but an
operation I don't see in the above is "put the working files into the
state of a given revision".

I recently needed this for some historical investigation,
(specifically examining all release tags to ensure that the results
after a git import match the results of what we get from the former
CVS repository).

In this kind of historical exploration, the notion of a "current
branch" isn't interesting, since I won't be doing any commits. So the
handling of the current branch in the above commands ends up getting
in my way [*].

Is there a more fundamental operation to "put the working files into
the state of the index"? If that exists, then that combined with
git-read-tree would give me what I wanted I think.

-Carl

[*] I did succeed in performing the operation, but only in rather
awkward ways. Here are a couple of versions of "put the working files
into the state of <revision>", both requiring the use of an otherwise
unnecessary branch, (bogus-branch):

1) Ensure bogus-branch doesn't exist, then create it at <revision>:

	# Can't be on bogus-branch when we delete it
	git checkout master
	# Use -D to force the removal, ignore errors for branch-does-not-exist
	git branch -D bogus-branch >& /dev/null || true
	# Create the branch where we want it
	git checkout -b bogus-branch <revision>

2) Ensure that bogus-branch exists somewhere (don't care where), then
   move it:

	# Create the branch (if it doesn't exist)
	git checkout -b bogus-branch >& /dev/null
	# Switch to it (which doesn't happen above if it already existed)
	git checkout bogus-branch
	# Move the branch to the revision of interest
	git reset --hard <revision>

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: several quick questions
From: Andreas Ericsson @ 2006-02-14 18:08 UTC (permalink / raw)
  To: Kenneth Johansson; +Cc: git
In-Reply-To: <pan.2006.02.14.17.47.53.126690@canit.se>

Kenneth Johansson wrote:
> 
> I'm not sure that many people will understand that they want git-reset for
> this just reading the man pages.
> 

Hence the tutorial.

-- 
Andreas Ericsson                   andreas.ericsson@op5.se
OP5 AB                             www.op5.se
Tel: +46 8-230225                  Fax: +46 8-230231

^ permalink raw reply

* [PATCH 2/2] Workaround git < 1.2.0 ignoring .gitignore in parent directories
From: Pavel Roskin @ 2006-02-14 18:05 UTC (permalink / raw)
  To: Petr Baudis; +Cc: git
In-Reply-To: <20060214180520.13766.78172.stgit@dv.roinet.com>

Add --exclude-from for all existing .gitignore files in parent
directories up to the repository root.  This is not needed for git 1.2.0
and newer.

Signed-off-by: Pavel Roskin <proski@gnu.org>
---

 cg-Xlib |   16 ++++++++++++++++
 1 files changed, 16 insertions(+), 0 deletions(-)

diff --git a/cg-Xlib b/cg-Xlib
index 85a21c2..af278b6 100644
--- a/cg-Xlib
+++ b/cg-Xlib
@@ -230,6 +230,22 @@ list_untracked_files()
 			EXCLUDE[${#EXCLUDE[@]}]="--exclude-from=$EXCLUDEFILE"
 		fi
 		EXCLUDE[${#EXCLUDE[@]}]="--exclude-per-directory=.gitignore"
+		# Workaround for git < 1.2.0
+		if [ -n "$_git_relpath" ]; then
+			local dir="${_git_relpath%/}"
+			local reldir=".."
+			while [ "$dir" != "." ]; do
+				if [ "${dir%/*}" = "$dir" ]; then
+					dir="."
+				else
+					dir="${dir%/*}"
+				fi
+				if [ -f "$reldir/.gitignore" ]; then
+					EXCLUDE[${#EXCLUDE[@]}]="--exclude-from=$dir/.gitignore"
+				fi
+				reldir="../$reldir"
+			done
+		fi
 	fi
 	local listdirs=
 	[ "$squashflag" = "squashdirs" ] && listdirs=--directory

^ permalink raw reply related

* [PATCH 1/2] cg-clean shouldn't clean untracked directories without -d
From: Pavel Roskin @ 2006-02-14 18:05 UTC (permalink / raw)
  To: Petr Baudis; +Cc: git

Use the new squashdirs argument in list_untracked_files() to treat
untracked directories and their contents as a whole.  Remove a separate
pass to find untracked directories.  Adjust the testsuite accordingly.

Don't change IFS - it's no longer needed.

Signed-off-by: Pavel Roskin <proski@gnu.org>
---

 cg-clean         |   99 ++++++++++--------------------------------------------
 t/t9400-clean.sh |    3 +-
 2 files changed, 20 insertions(+), 82 deletions(-)

diff --git a/cg-clean b/cg-clean
index b40b41b..5c27a26 100755
--- a/cg-clean
+++ b/cg-clean
@@ -53,88 +53,27 @@ done
 
 [ ${#ARGS[*]} = 0 ] || usage
 
-
-clean_dirs()
-{
-	dirlist="$(mktemp -t gitlsfiles.XXXXXX)"
-	git-ls-files --cached |
-		sed -n 's|/[^/]*$||p' |
-		while IFS=$'\n' read -r dir; do
-			while true; do
-				echo "$dir"
-				updir="${dir%/*}"
-				[ "$dir" = "$updir" ] && break
-				dir="$updir"
-			done
-		done |
-		sort -u >"$dirlist"
-
-	save_IFS="$IFS"
-	IFS=$'\n'
-
-	find ./ -type d -print |
-		sed 's/^\.\///;/^$/d;/^\.git$/d;/^\.git\//d' |
-		cat - "$dirlist" | sort -u |
-		diff - "$dirlist" |
-		sed -n 's/< //p' |
-	while read -r dir; do
-		if [ ! -d "$dir" ]; then
-			# Perhaps directory was removed with its parent
-			continue
-		fi
+cd "${_git_relpath-.}"
+list_untracked_files "$noexclude" squashdirs | tr '\0' '\n' |
+while read -r file; do
+	if [ -d "$file" -a ! -L "$file" ]; then
 		if [ -z "$cleandir" ]; then
-			echo "Not removing $dir/"
+			echo "Not removing $file"
 			continue
 		fi
-		[ "$quiet" ] || echo "Removing $dir/"
+		[ "$quiet" ] || echo "Removing $file"
 		if [ "$cleandirhard" ]; then
-			chmod -R 700 "$dir"
+			chmod -R 700 "$file"
 		fi
-		$rm -rf "$dir"
-		if [ -e "$dir" -o -L "$dir" ]; then
-			echo "Cannot remove $dir/"
-		fi
-	done
-
-	IFS="$save_IFS"
-	rm "$dirlist"
-}
-
-clean_files()
-{
-	save_IFS="$IFS"
-	IFS=$'\n'
-
-	list_untracked_files "$noexclude" nosquashdirs | tr '\0' '\n' |
-	(cd "${_git_relpath-.}" &&
-	while read -r file; do
-		if [ -z "$_git_relpath" ] || [ x"${file#$_git_relpath}" != x"$file" ]; then
-			file="${file#$_git_relpath}"
-		else
-			continue
-		fi
-
-		if [ -d "$file" -a ! -L "$file" ]; then
-			# Sanity check, shouldn't happen
-			echo "FATAL: cg-status reports directories (internal error)" >&2
-			exit 1
-		elif [ -e "$file" -o -L "$file" ]; then
-			[ "$quiet" ] || echo "Removing $file"
-			"$rm" -f "$file"
-			# rm would complain itself on failure
-		else
-			echo "File $file has disappeared!"
-		fi
-	done)
-
-	IFS="$save_IFS"
-}
-
-
-# Even if -d or -D is not specified, we want to tell user about
-# directories that are not removed
-if [ -z "$quiet" -o "$cleandir" ]; then
-	( cd "${_git_relpath-.}" && clean_dirs )
-fi
-
-clean_files
+		$rm -rf "$file"
+		if [ -e "$file" -o -L "$file" ]; then
+			echo "Cannot remove $file"
+		fi
+	elif [ -e "$file" -o -L "$file" ]; then
+		[ "$quiet" ] || echo "Removing $file"
+		"$rm" -f "$file"
+		# rm would complain itself on failure
+	else
+		echo "File $file has disappeared!"
+	fi
+done
diff --git a/t/t9400-clean.sh b/t/t9400-clean.sh
index 47ae0dc..98801c5 100755
--- a/t/t9400-clean.sh
+++ b/t/t9400-clean.sh
@@ -84,10 +84,8 @@ echo "ign file 3" >"repo dir/ign file 3.
 echo "ign file 4" >"repo dir/ign file 4.ign1"
 mklist init
 
-# FIXME: cg-clean shouldn't clean unknown directories without "-d"
 loss='extra file 1
 ign file 2.ign1
-extra dir 1/extra file 3
 repo dir/extra file 2'
 test_expect_success 'cg-clean in top-level dir' \
 	"(cg-clean && check_loss)"
@@ -99,6 +97,7 @@ test_expect_success 'cg-clean -x in top-
 	"(cg-clean -x && check_loss)"
 
 loss='extra dir 1
+extra dir 1/extra file 3
 repo dir/extra dir 2'
 test_expect_success 'cg-clean -d in top-level dir' \
 	"(cg-clean -d && check_loss)"

^ permalink raw reply related

* Re: several quick questions
From: Kenneth Johansson @ 2006-02-14 17:47 UTC (permalink / raw)
  To: git
In-Reply-To: <Pine.LNX.4.64.0602140845080.3691@g5.osdl.org>

On Tue, 14 Feb 2006 09:05:16 -0800, Linus Torvalds wrote:

> 
> 
> On Tue, 14 Feb 2006, Nicolas Vilz 'niv' wrote:
>> 
>> i wonder, how i revoke a straight forward merge of two trees... I
>> actually wanted to be look like somewhere in the git-repository, where
>> some branches are merged back with the master tree, but i think, that
>> wasn't "cg-merge -c <tree to merge with the actual one>"...
>> 
>> my result was that my master tree has now the same sha1-sum as my
>> development-tree and gitk visualisation differs from that what i saw in
>> the git-repository. (Several Arrows headed into back into one line...)
>> 
>> maybe that was because i didn't do anything in my master tree in the
>> meantime.
>> 
>> And another thing, is there no posibility to get back to some commits or
>> tags? I realized you can rebranch tags... what, if i want to switch back
>> to git version 1.1.6 in the git repository? Or a certain commit?
> 
> Both of these can be solved with "git reset".

I also had this exact question today since I wanted to compile an earlier
version of the kernel and like Nicolas I naturally got stuck on the
checkout command and that dose not work like one would think.

What I ended up doing was going nee deep into the plumbing.

first doing cat on the tag in .git/refs/tags/ 
taking the output as an argument to  "git-read-tree"
followed by "git-update-index --replace" and "git-checkout-index -a -f -u"

I'm not sure that many people will understand that they want git-reset for
this just reading the man pages.

^ permalink raw reply

* bug: stgit doesn't handle branch names with / in them
From: Karl Hasselström @ 2006-02-14 17:35 UTC (permalink / raw)
  To: Catalin Marinas; +Cc: git

"stg branch -l" only shows branches directly under refs/heads, and
completely ignores branches in subdirectories. But it does print the
name of the subdirectories . . .

"stg branch" prints only the part of the branch name following the
final slash.

    $ git-branch
      kha/abc123
      kha/dab
    * kha/patches
      kha/powerup
      kha/dare
      kha/dare-build
      kha/boo123
      kha/lisp106
      local/test0
      local/test3
      local/test4
      SVN-import
      test5

    $ stg branch -l
    Available branches:
            SVN-import  |
            kha         |
            local       |
            test5       |

    $ stg branch
    patches

No patch (yet), sorry.

-- 
Karl Hasselström, kha@treskal.com
      www.treskal.com/kalle

^ permalink raw reply

* Re: git-svnimport issue with rename+change in the same commit
From: Manu @ 2006-02-14 17:29 UTC (permalink / raw)
  To: Eduardo Pereira Habkost; +Cc: git
In-Reply-To: <20060214171233.GC4381@duckman.conectiva>

Hi,
Eduardo Pereira Habkost wrote:
 > Hi,
 >
 > I've just hit a problem when using git-svnimport to import a big
 > subversion repository: it doesn't import correctly a commit when the
 > commit renames (or copies) and modify a file at the same time.

I came accross the same problem myself. Here is a patch that seemed to 
do the trick for me.
I tried your script, and it also seems to work.
Regards,

Emmanuel

---

[PATCH] git-svnimport: Correction when a "copy_path" has different 
contents for src and dest.

In my SVN repository, there is a weird log:

   A /trunk/mydir2 (from /trunk/mydir1:4)
   R /trunk/mydir2/test.txt (from /trunk/mydir1/test.txt:4)

As a result, mydir2/test.txt is different than mydir1/test.txt, but
git-svnimport assumes that the content of mydir2/test.txt is the same
as mydir1/test.txt.

This patch adds a test in copy_path, that makes sure that src and dest
have the same content. If not, it uses the content of dest.

---

 git-svnimport.perl |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

e107ff9a06497a0003036ffafa45fa9dc050ecc4
diff --git a/git-svnimport.perl b/git-svnimport.perl
index f17d5a2..a2faa9a 100755
--- a/git-svnimport.perl
+++ b/git-svnimport.perl
@@ -409,6 +409,12 @@ sub copy_path($$$$$$$$) {
             $p = $path . substr($p,length($srcpath)-1);
         } else {
             $p = $path;
+            # Deal with copy and modification
+            my $f=get_file($newrev,$newbranch,$path);
+            my ($tmode,$tsha1,$tp)=@$f;
+            if ($tsha1 ne $sha1) {
+                $sha1=$tsha1;
+            }
         }
         push(@$new,[$mode,$sha1,$p]);   
     }
-- 
1.1.GIT

^ permalink raw reply related

* git-svnimport issue with rename+change in the same commit
From: Eduardo Pereira Habkost @ 2006-02-14 17:12 UTC (permalink / raw)
  To: git

[-- Attachment #1: Type: text/plain, Size: 1708 bytes --]

Hi,

I've just hit a problem when using git-svnimport to import a big
subversion repository: it doesn't import correctly a commit when the
commit renames (or copies) and modify a file at the same time.

At the bottom of this message, there is a script that reproduces the bug.

The result of the final 'diff' command on the script is:

diff -u --exclude .git --exclude .svn checkout/universe.py
git/universe.py
--- checkout/universe.py        2006-02-14 14:55:37.000000000 -0200
+++ git/universe.py     2006-02-14 14:55:38.000000000 -0200
@@ -1 +1 @@
-print "Hello, universe!"
+print "Hello, world!"

git-svnadmin is just taking the original version of the file when
the commit has a 'file copy', even if this copy was modified before
the commit.

However I can't see a way to fix this problem without making the script
ignore completely the the "copied from" information from the svn commits
(and always fetching the resulting files from the repository). It seems
that subversion doesn't tell us if the copied file was changed (or this
information is hidden somewhere else).

-- 
Eduardo


#!/bin/sh
set -e

mkdir repos
svnadmin create $PWD/repos
repos=file://$PWD/repos
svn mkdir $repos/trunk -m 'creating trunk'
svn co file://$PWD/repos/trunk checkout
cd checkout
cat >hello.py <<EOF
print "Hello, world!"
EOF
svn add hello.py
svn commit -m 'adding hello.py'
svn mv hello.py world.py
svn commit -m 'renaming to world.py'
svn mv world.py universe.py
sed -i -e 's/world/universe/' universe.py
svn commit -m 'universe, now'
cd ..
mkdir git
cd git
git svnimport $repos
cd ..
diff -u --exclude .git --exclude .svn checkout git # will report differences

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: several quick questions
From: Linus Torvalds @ 2006-02-14 17:05 UTC (permalink / raw)
  To: Nicolas Vilz 'niv'; +Cc: git
In-Reply-To: <43F20532.5000609@iaglans.de>



On Tue, 14 Feb 2006, Nicolas Vilz 'niv' wrote:
> 
> i wonder, how i revoke a straight forward merge of two trees... I
> actually wanted to be look like somewhere in the git-repository, where
> some branches are merged back with the master tree, but i think, that
> wasn't "cg-merge -c <tree to merge with the actual one>"...
> 
> my result was that my master tree has now the same sha1-sum as my
> development-tree and gitk visualisation differs from that what i saw in
> the git-repository. (Several Arrows headed into back into one line...)
> 
> maybe that was because i didn't do anything in my master tree in the
> meantime.
> 
> And another thing, is there no posibility to get back to some commits or
> tags? I realized you can rebranch tags... what, if i want to switch back
> to git version 1.1.6 in the git repository? Or a certain commit?

Both of these can be solved with "git reset".

Before going into any more detail on that, let's go over the other related 
"basic operations" too:

 - "git branch". This creates a new branch of development at an arbitrary 
   point (that defaults to "current state").

   Example:

	git branch development-trial v1.1.6

   This will create a new branch called "development-trial", which starts 
   at the v1.1.6 state. NOTE! It will _not_ check it out - your old active 
   state is left totally alone, and you still stay on whatever branch you 
   used to be on.

 - "git checkout". This switches to another branch. As a shorthand, you 
   can also choose to create the branch at the same time, but normally 
   you'd just do like this example:

	git checkout development-trial

   which will switch to the branch you just created and check that out.

 - "git reset". This will reset the current branch state to something 
   else. This is what you would use if you want to undo a commit, 
   for example: you can "reset" the current branch to before the commit 
   happened.

   NOTE! When you do this, you also have to choose what you want to do 
   about your checked-out working tree. For example, when undoing the last 
   commit, you normally want to totally undo all the working tree changes 
   too, but you might also want to just undo the commit, and leave the 
   actual changes you committed alone, so that you can re-commit them with 
   a fixed commit message, for example.

   Example:

	git reset --hard HEAD^

   this will undo the last commit (more exactly: it will select the first 
   parent of HEAD to be the new top-of-development, so if the last thing 
   you did was a merge, it will reset to the previous state). The "--hard" 
   means that you want to reset the working tree too.

   Other example:

	git reset --hard v1.1.6

   This will just reset the current branch to a particular known state (ie 
   1.1.6 in this case).

   Without the "--hard", it will _not_ change the working tree, but just 
   update the index (and branch pointer, of course) to the new state, and 
   tell you which files are "dirty" in that new state. This is great for 
   undoing just a "git commit", but leaving the tree in the state is was 
   before you committed. It's not so great if you expected to revert 
   everything, and are now confused because "git diff" shows lots of 
   changes ;)

Finally, let's go over the difference between "git fetch" and "git pull":

 - "git fetch" is what you want to do if you want to _update_ another 
   branch. For example, if you want to track what Junio is doing in his 
   git repository (assuming that was what you cloned for), doing

	git fetch origin

   will update the "origin" branch, but will _not_ touch the current 
   branch itself. This is very useful for seeing what Junio has been 
   doing, without actually affecting your own work in any way.

 - "git pull" is really just "git fetch" + "git merge". It will fetch the 
   state you asked for, and then merge that into your current branch. So 
   it's important to rmember that this actually _changes_ what you have 
   checked out and have worked on. 

   One very special case of "git pull" is when you only use the repository 
   to track another branch, and you never do any changes at all, and you 
   never switch branches around, and you always pull from the same source. 
   In that case, "git pull" will basically boil down to just a read-only 
   tracking mechanism (ie you could think of this particular usage as 
   being the git equivalent of "anoncvs" access)

The reason people may get confused is that they start out using "git pull" 
as a read-only tracking mechanism, and it's not necessarily obvious that 
"git pull" really fundamentally is a very powerful operations - much MUCH 
more complex and powerful than just "track that other branch". Which is 
why I try to make the distinction between "git fetch" and "git pull" 
clear.

			Linus

^ permalink raw reply

* Re: several quick questions
From: Andreas Ericsson @ 2006-02-14 17:03 UTC (permalink / raw)
  To: Nicolas Vilz 'niv'; +Cc: git
In-Reply-To: <43F20532.5000609@iaglans.de>

Nicolas Vilz 'niv' wrote:
> Hello everyone,
> 
> i wonder, how i revoke a straight forward merge of two trees... I
> actually wanted to be look like somewhere in the git-repository, where
> some branches are merged back with the master tree, but i think, that
> wasn't "cg-merge -c <tree to merge with the actual one>"...
> 
> my result was that my master tree has now the same sha1-sum as my
> development-tree and gitk visualisation differs from that what i saw in
> the git-repository. (Several Arrows headed into back into one line...)
> 
> maybe that was because i didn't do anything in my master tree in the
> meantime.
> 

Correct. The "several arrows" thing is when a merge happens (i.e. two 
simultaneous lines of development crash into one another with 
surprisingly pleasant results most of the time). When you do

$ git checkout -b topic-branch
# work, work, work
$ git checkout master
$ git pull . topic-branch

git will recognize the merge-base as being the current HEAD and simply 
sets HEAD to point to that of topic-branch. This is why it's called a 
fast-forward, since no heavy computing needs to be done to combine the 
two development tracks.

> And another thing, is there no posibility to get back to some commits or
> tags? I realized you can rebranch tags... what, if i want to switch back
> to git version 1.1.6 in the git repository? Or a certain commit?
> 

git reset is your friend.

$ git reset --hard v1.1.6
$ git reset --hard ORIG_HEAD

should do something along the lines of what you want.

> do you have to make a new private branch out of the tag 1.1.6?
> 

No, you don't, but you can if you wish. It's nifty if you want to fork 
the development from a particular branch. In your case, if you really, 
really *want* the arrows pointing to one line, you can do

$ git branch topic-branch HEAD^
# work, work, work
$ git checkout master
$ git pull . topic-branch

That would create one pretty arrow. When multiple tracks of development 
(rather than just two) are combined into one it's called an octopus 
merge. Unless you really know what you're doing, you should try to avoid 
those for small projects, and doing it just for the pretty arrows is.... 
well, let's call it "interesting from the behaviour science scholars 
point of view".


> i used svn and there i could go back some revisions. I haven't found
> such a feature in git, yet... but i think i am blind all the time.
> 

Most likely. I believe at least the reset command is mentioned in the 
tutorial. I trust you've read it before asking, so something is amiss 
either with your eyesight or the tutorial.


> I like git very much and every new day I like it more.
> 

It's a Good Thing. ;)

-- 
Andreas Ericsson                   andreas.ericsson@op5.se
OP5 AB                             www.op5.se
Tel: +46 8-230225                  Fax: +46 8-230231

^ permalink raw reply

* several quick questions
From: Nicolas Vilz 'niv' @ 2006-02-14 16:28 UTC (permalink / raw)
  To: git

Hello everyone,

i wonder, how i revoke a straight forward merge of two trees... I
actually wanted to be look like somewhere in the git-repository, where
some branches are merged back with the master tree, but i think, that
wasn't "cg-merge -c <tree to merge with the actual one>"...

my result was that my master tree has now the same sha1-sum as my
development-tree and gitk visualisation differs from that what i saw in
the git-repository. (Several Arrows headed into back into one line...)

maybe that was because i didn't do anything in my master tree in the
meantime.

And another thing, is there no posibility to get back to some commits or
tags? I realized you can rebranch tags... what, if i want to switch back
to git version 1.1.6 in the git repository? Or a certain commit?

do you have to make a new private branch out of the tag 1.1.6?

i used svn and there i could go back some revisions. I haven't found
such a feature in git, yet... but i think i am blind all the time.

I like git very much and every new day I like it more.

Sincerly
Nicolas

^ permalink raw reply

* Re: [ANNOUNCE] pg - A patch porcelain for GIT
From: Karl Hasselström @ 2006-02-14 16:07 UTC (permalink / raw)
  To: Chuck Lever; +Cc: Catalin Marinas, git
In-Reply-To: <43F1F5CB.10402@citi.umich.edu>

On 2006-02-14 10:22:51 -0500, Chuck Lever wrote:

> Karl Hasselström wrote:
>
> > One thing I would like to see in stgit is the opposite of "stg
> > commit"; instead of converting patches to regular commits, take
> > the topmost regular commits and convert them to patches.
> >
> > For example, "stg uncommit foo bar baz" would -- regardless of any
> > existing patches, applied or not -- convert the top three regular
> > commits, with comments and all, to stgit patches called foo, bar,
> > and baz. These would be already applied, at the bottom of the
> > stack. I imagine all one would have to do is to modify some stgit
> > metadata, so the operation could be really cheap.
> >
> > Of course, "stg uncommit" is allowed to reject any commit with
> > more than one parent, since those can't be represented as stgit
> > patches.
> >
> > This would perhaps not add much power to an all-stgit workflow,
> > but it would be a really convenient way to edit recent git
> > history. Sort of like a more convenient rebase. And a great way to
> > lure new users. :-)
>
> i think you want "stg pick --reverse" ?

No, I literally want the opposite of "stg commit", so that the
sequence "stg commit; stg uncommit" has zero net effect.

Say we have the following situation (stack growing downward, of
course):

          :
          |
          a
          |
          b
          |
          c <- bases/master
          |
          d <- applied patch "foo"
          |
          e <- applied patch "bar"; HEAD
          |
          f <- unapplied patch "baz"
          |
          :

In this situation, the hypothetical "stg uncommit" command would have
the following effect:

  $ stg uncommit goo baa

          :
          |
          a <- bases/master
          |
          b <- applied patch "baa"
          |
          c <- applied patch "goo"
          |
          d <- applied patch "foo"
          |
          e <- applied patch "bar"; HEAD
          |
          f <- unapplied patch "baz"
          |
          :

Note that HEAD is unchanged; the only thing that has happend is that
stgit has taken over the topmost two commits, and turned them into
patches. No git operations whatsoever have taken place; all stgit had
to do was change the value of bases/master and add bookkeeping
information for the two new patches.

-- 
Karl Hasselström, kha@treskal.com
      www.treskal.com/kalle

^ permalink raw reply

* Re: cg-clean, cg-status improvements
From: Petr Baudis @ 2006-02-14 15:53 UTC (permalink / raw)
  To: Pavel Roskin; +Cc: git
In-Reply-To: <1139930899.1944.13.camel@dv>

  Hello,

Dear diary, on Tue, Feb 14, 2006 at 04:28:19PM CET, I got a letter
where Pavel Roskin <proski@gnu.org> said that...
> Hello, Petr!
> 
> Is cogito 0.17 going to require git 1.2.0?  If so, I'm ready to submit a
> patch for cg-clean that would use the fixed functionality of git
> regarding ignores when run in subdirectories (commit
> 701ca744e386c2429ca44072ea987bbb4bdac7ce).  I think cg-status can be
> improved as well.
> 
> If cogito 0.17 is not going to require git 1.2.0, I'm ready to add a
> temporary workaround for older versions of git.

  I didn't plan to require git 1.2.0 with 0.17, so it would be better if
you could do the workaround. But if the workaround means significant
hassle, it's no biggie if git 1.2.0 will be required.

> The problem with cg-clean right now is that it removes contents of
> untracked directories by default, which makes it pointless to keep the
> directories.  I submitted a patch for that, but it it wasn't noticed.
> Anyway, I can do it better now.

  Hmm, strange, I really did not notice the patch. Well, I'm certainly
interested.

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
Of the 3 great composers Mozart tells us what it's like to be human,
Beethoven tells us what it's like to be Beethoven and Bach tells us
what it's like to be the universe.  -- Douglas Adams

^ permalink raw reply

* cg-clean, cg-status improvements
From: Pavel Roskin @ 2006-02-14 15:28 UTC (permalink / raw)
  To: Petr Baudis, git

Hello, Petr!

Is cogito 0.17 going to require git 1.2.0?  If so, I'm ready to submit a
patch for cg-clean that would use the fixed functionality of git
regarding ignores when run in subdirectories (commit
701ca744e386c2429ca44072ea987bbb4bdac7ce).  I think cg-status can be
improved as well.

If cogito 0.17 is not going to require git 1.2.0, I'm ready to add a
temporary workaround for older versions of git.

The problem with cg-clean right now is that it removes contents of
untracked directories by default, which makes it pointless to keep the
directories.  I submitted a patch for that, but it it wasn't noticed.
Anyway, I can do it better now.

-- 
Regards,
Pavel Roskin

^ permalink raw reply

* Re: [ANNOUNCE] pg - A patch porcelain for GIT
From: Chuck Lever @ 2006-02-14 15:22 UTC (permalink / raw)
  To: Karl Hasselström; +Cc: Catalin Marinas, git
In-Reply-To: <20060214100844.GA1234@diana.vm.bytemark.co.uk>

[-- Attachment #1: Type: text/plain, Size: 1257 bytes --]

Karl Hasselström wrote:
> On 2006-02-14 09:26:41 +0000, Catalin Marinas wrote:
> 
> 
>>Another thing that's missing in StGIT is the import of a series of
>>patches. At the moment I run a small shell script to import
>>individual patches.
> 
> 
> One thing I would like to see in stgit is the opposite of "stg
> commit"; instead of converting patches to regular commits, take the
> topmost regular commits and convert them to patches.
> 
> For example, "stg uncommit foo bar baz" would -- regardless of any
> existing patches, applied or not -- convert the top three regular
> commits, with comments and all, to stgit patches called foo, bar, and
> baz. These would be already applied, at the bottom of the stack. I
> imagine all one would have to do is to modify some stgit metadata, so
> the operation could be really cheap.
> 
> Of course, "stg uncommit" is allowed to reject any commit with more
> than one parent, since those can't be represented as stgit patches.
> 
> This would perhaps not add much power to an all-stgit workflow, but it
> would be a really convenient way to edit recent git history. Sort of
> like a more convenient rebase. And a great way to lure new users. :-)

i think you want "stg pick --reverse" ?

[-- Attachment #2: cel.vcf --]
[-- Type: text/x-vcard, Size: 451 bytes --]

begin:vcard
fn:Chuck Lever
n:Lever;Charles
org:Network Appliance, Incorporated;Open Source NFS Client Development
adr:535 West William Street, Suite 3100;;Center for Information Technology Integration;Ann Arbor;MI;48103-4943;USA
email;internet:cel@citi.umich.edu
title:Member of Technical Staff
tel;work:+1 734 763-4415
tel;fax:+1 734 763 4434
tel;home:+1 734 668-1089
x-mozilla-html:FALSE
url:http://troy.citi.umich.edu/u/cel/
version:2.1
end:vcard


^ permalink raw reply

* Re: [PATCH] Add git-annotate - a tool for annotating files with the revision and person that created each line in the file.
From: Fredrik Kuivinen @ 2006-02-14 10:51 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: Junio C Hamano, Johannes Schindelin, Franck Bui-Huu, git
In-Reply-To: <20060210112541.GA3513@linux-mips.org>

On Fri, Feb 10, 2006 at 11:25:41AM +0000, Ralf Baechle wrote:
> The dependency on Python 2.4 already is a problem for installation on some
> systems ... 

I understand that in the environments where the Python dependency is a
problem it is probably not due to the specific version. However, if
WITH_OWN_SUBPROCESS is defined in the Makefile then Python 2.3 should
work fine too (this is actually automatically detected now, so you
shouldn't have to do anything special to use Python 2.3).

- Fredrik

^ permalink raw reply

* Re: [ANNOUNCE] pg - A patch porcelain for GIT
From: Karl Hasselström @ 2006-02-14 10:08 UTC (permalink / raw)
  To: Catalin Marinas; +Cc: git
In-Reply-To: <tnxoe1aqoj2.fsf@arm.com>

On 2006-02-14 09:26:41 +0000, Catalin Marinas wrote:

> Another thing that's missing in StGIT is the import of a series of
> patches. At the moment I run a small shell script to import
> individual patches.

One thing I would like to see in stgit is the opposite of "stg
commit"; instead of converting patches to regular commits, take the
topmost regular commits and convert them to patches.

For example, "stg uncommit foo bar baz" would -- regardless of any
existing patches, applied or not -- convert the top three regular
commits, with comments and all, to stgit patches called foo, bar, and
baz. These would be already applied, at the bottom of the stack. I
imagine all one would have to do is to modify some stgit metadata, so
the operation could be really cheap.

Of course, "stg uncommit" is allowed to reject any commit with more
than one parent, since those can't be represented as stgit patches.

This would perhaps not add much power to an all-stgit workflow, but it
would be a really convenient way to edit recent git history. Sort of
like a more convenient rebase. And a great way to lure new users. :-)

-- 
Karl Hasselström, kha@treskal.com
      www.treskal.com/kalle

^ permalink raw reply

* Re: [ANNOUNCE] pg - A patch porcelain for GIT
From: Catalin Marinas @ 2006-02-14  9:26 UTC (permalink / raw)
  To: Petr Baudis; +Cc: git
In-Reply-To: <20060213210001.GA31278@pasky.or.cz>

Petr Baudis <pasky@suse.cz> wrote:
>   Some common gripes for both StGIT and pg (well, I'm using some
> ridiculously old StGIT version, so this may not apply anymore there):
>
> 	* stg new --force - seriously, what's the point?! I always to
> 	the change first and when it's any good, I want to create a
> 	patch for it.

This was fixed couple of weeks ago in the main branch. No need to pass
--force anymore.

> 	* I can't just get the patch in its "canonical ready-to-mail
> 	form" on stdout so that I could easily review it. Why is
> 	pg-export insisting to dump it to a file?

To view the patch you can use 'stg diff -r <patch>/' but it doesn't
show the description. Dumping the full patch on stdout would be
useful, indeed. The export and mail commands use different templates
and the latter even adds the standard mail headers. Which of these two
commands would you prefer to dump the patch on stdout (both is fine as
well)?

Another thing that's missing in StGIT is the import of a series of
patches. At the moment I run a small shell script to import individual
patches.

-- 
Catalin

^ permalink raw reply

* [PATCH] rebase: allow a hook to refuse rebasing.
From: Junio C Hamano @ 2006-02-14  7:53 UTC (permalink / raw)
  To: git

This lets a hook to interfere a rebase and help prevent certain
branches from being rebased by mistake.  A sample hook to show
how to prevent a topic branch that has already been merged into
publish branch.

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

---

 * This was done while switching my workflow to more stable
   "next".  A companion script which is more private nature is
   in the TODO branch, file TO.  I use that one to manage the
   "next" branch, and this sample hook prevents me from rebasing
   topic branches too eagerly by mistake.

 git-rebase.sh               |    9 +++
 templates/hooks--pre-rebase |  150 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 159 insertions(+), 0 deletions(-)
 create mode 100644 templates/hooks--pre-rebase

9a111c91b01455ee1ea9f33c60da7ad50d460a7b
diff --git a/git-rebase.sh b/git-rebase.sh
index 16d4359..f84160d 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -36,6 +36,15 @@ other=$(git-rev-parse --verify "$1^0") |
 # Make sure the branch to rebase is valid.
 head=$(git-rev-parse --verify "${2-HEAD}^0") || exit
 
+# If a hook exists, give it a chance to interrupt
+if test -x "$GIT_DIR/hooks/pre-rebase"
+then
+	"$GIT_DIR/hooks/pre-rebase" ${1+"$@"} || {
+		echo >&2 "The pre-rebase hook refused to rebase."
+		exit 1
+	}
+fi
+
 # If the branch to rebase is given, first switch to it.
 case "$#" in
 2)
diff --git a/templates/hooks--pre-rebase b/templates/hooks--pre-rebase
new file mode 100644
index 0000000..981c454
--- /dev/null
+++ b/templates/hooks--pre-rebase
@@ -0,0 +1,150 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 Junio C Hamano
+#
+
+publish=next
+basebranch="$1"
+if test "$#" = 2
+then
+	topic="refs/heads/$2"
+else
+	topic=`git symbolic-ref HEAD`
+fi
+
+case "$basebranch,$topic" in
+master,refs/heads/??/*)
+	;;
+*)
+	exit 0 ;# we do not interrupt others.
+	;;
+esac
+
+# Now we are dealing with a topic branch being rebased
+# on top of master.  Is it OK to rebase it?
+
+# Is topic fully merged to master?
+not_in_master=`git-rev-list --pretty=oneline ^master "$topic"`
+if test -z "$not_in_master"
+then
+	echo >&2 "$topic is fully merged to master; better remove it."
+	exit 1 ;# we could allow it, but there is no point.
+fi
+
+# Is topic ever merged to next?  If so you should not be rebasing it.
+only_next_1=`git-rev-list ^master "^$topic" ${publish} | sort`
+only_next_2=`git-rev-list ^master           ${publish} | sort`
+if test "$only_next_1" = "$only_next_2"
+then
+	not_in_topic=`git-rev-list "^$topic" master`
+	if test -z "$not_in_topic"
+	then
+		echo >&2 "$topic is already up-to-date with master"
+		exit 1 ;# we could allow it, but there is no point.
+	else
+		exit 0
+	fi
+else
+	not_in_next=`git-rev-list --pretty=oneline ^${publish} "$topic"`
+	perl -e '
+		my $topic = $ARGV[0];
+		my $msg = "* $topic has commits already merged to public branch:\n";
+		my (%not_in_next) = map {
+			/^([0-9a-f]+) /;
+			($1 => 1);
+		} split(/\n/, $ARGV[1]);
+		for my $elem (map {
+				/^([0-9a-f]+) (.*)$/;
+				[$1 => $2];
+			} split(/\n/, $ARGV[2])) {
+			if (!exists $not_in_next{$elem->[0]}) {
+				if ($msg) {
+					print STDERR $msg;
+					undef $msg;
+				}
+				print STDERR " $elem->[1]\n";
+			}
+		}
+	' "$topic" "$not_in_next" "$not_in_master"
+	exit 1
+fi
+
+exit 0
+
+################################################################
+
+This sample hook safeguards topic branches that have been
+published from being rewound.
+
+The workflow assumed here is:
+
+ * Once a topic branch forks from "master", "master" is never
+   merged into it again (either directly or indirectly).
+
+ * Once a topic branch is fully cooked and merged into "master",
+   it is deleted.  If you need to build on top of it to correct
+   earlier mistakes, a new topic branch is created by forking at
+   the tip of the "master".  This is not strictly necessary, but
+   it makes it easier to keep your history simple.
+
+ * Whenever you need to test or publish your changes to topic
+   branches, merge them into "next" branch.
+
+The script, being an example, hardcodes the publish branch name
+to be "next", but it is trivial to make it configurable via
+$GIT_DIR/config mechanism.
+
+With this workflow, you would want to know:
+
+(1) ... if a topic branch has ever been merged to "next".  Young
+    topic branches can have stupid mistakes you would rather
+    clean up before publishing, and things that have not been
+    merged into other branches can be easily rebased without
+    affecting other people.  But once it is published, you would
+    not want to rewind it.
+
+(2) ... if a topic branch has been fully merged to "master".
+    Then you can delete it.  More importantly, you should not
+    build on top of it -- other people may already want to
+    change things related to the topic as patches against your
+    "master", so if you need further changes, it is better to
+    fork the topic (perhaps with the same name) afresh from the
+    tip of "master".
+
+Let's look at this example:
+
+		   o---o---o---o---o---o---o---o---o---o "next"
+		  /       /           /           /
+		 /   a---a---b A     /           /
+		/   /               /           /
+	       /   /   c---c---c---c B         /
+	      /   /   /             \         /
+	     /   /   /   b---b C     \       /
+	    /   /   /   /             \     /
+    ---o---o---o---o---o---o---o---o---o---o---o "master"
+
+
+A, B and C are topic branches.
+
+ * A has one fix since it was merged up to "next".
+
+ * B has finished.  It has been fully merged up to "master" and "next",
+   and is ready to be deleted.
+
+ * C has not merged to "next" at all.
+
+We would want to allow C to be rebased, refuse A, and encourage
+B to be deleted.
+
+To compute (1):
+
+	git-rev-list ^master ^topic next
+	git-rev-list ^master        next
+
+	if these match, topic has not merged in next at all.
+
+To compute (2):
+
+	git-rev-list master..topic
+
+	if this is empty, it is fully merged to "master".
-- 
1.2.0.g45dc

^ permalink raw reply related


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