Git development
 help / color / mirror / Atom feed
* Re: [PATCH 1/3] configure: Add test for Perl
From: Alex Riesen @ 2006-07-06 15:40 UTC (permalink / raw)
  To: Dennis Stosberg; +Cc: git
In-Reply-To: <20060706124025.G325584e9@leonov.stosberg.net>

On 7/6/06, Dennis Stosberg <dennis@stosberg.net> wrote:
>  Miscellaneous options:
>    --cc=COMPILER          use this C compiler to build MPlayer [gcc]

Is it still MPlayer's?

^ permalink raw reply

* Re: [PATCH 1/3] configure: Add test for Perl
From: Dennis Stosberg @ 2006-07-06 15:44 UTC (permalink / raw)
  To: Alex Riesen; +Cc: git
In-Reply-To: <81b0412b0607060840g4df16edbm7df69d6c8edcc071@mail.gmail.com>

Alex Riesen wrote:

> Is it still MPlayer's?

That is being fixed in the third patch.

Regards,
Dennis

^ permalink raw reply

* More fully-fleshed-out builtin "git prune"
From: Linus Torvalds @ 2006-07-06 17:16 UTC (permalink / raw)
  To: Junio C Hamano, Git Mailing List


This actually removes the objects to be pruned, unless you specify "-n" 
(at which point it will just tell you which files it would prune).

This doesn't do the pack-file pruning that the shell-script used to do, 
but if somebody really wants to, they could add it easily enough. I wonder 
how useful it is, though, considering that "git repack -a -d" is just a 
lot more efficient and generates a better end result.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---

I've tested this somewhat, including the "object only reachable through 
the index" case, and used it to do a few real prunes. It's a lot faster 
(because it only does the trivial reachability part), and it all _seems_ 
fine and the code is fairly obvious and certainly simple enough. 

That said, this is "git prune". Getting things wrong here would be bad. 
People should double- and triple-check this.

 Makefile        |    4 -
 builtin-prune.c |  259 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 builtin.h       |    2 
 git-prune.sh    |   44 ---------
 git.c           |    3 -
 5 files changed, 265 insertions(+), 47 deletions(-)

diff --git a/Makefile b/Makefile
index 7fa4a27..d355622 100644
--- a/Makefile
+++ b/Makefile
@@ -120,7 +120,7 @@ SCRIPT_SH = \
 	git-fetch.sh \
 	git-ls-remote.sh \
 	git-merge-one-file.sh git-parse-remote.sh \
-	git-prune.sh git-pull.sh git-rebase.sh \
+	git-pull.sh git-rebase.sh \
 	git-repack.sh git-request-pull.sh git-reset.sh \
 	git-resolve.sh git-revert.sh git-sh-setup.sh \
 	git-tag.sh git-verify-tag.sh \
@@ -230,7 +230,7 @@ BUILTIN_OBJS = \
 	builtin-apply.o builtin-show-branch.o builtin-diff-files.o \
 	builtin-diff-index.o builtin-diff-stages.o builtin-diff-tree.o \
 	builtin-cat-file.o builtin-mailsplit.o builtin-stripspace.o \
-	builtin-update-ref.o builtin-fmt-merge-msg.o
+	builtin-update-ref.o builtin-fmt-merge-msg.o builtin-prune.o
 
 GITLIBS = $(LIB_FILE) $(XDIFF_LIB)
 LIBS = $(GITLIBS) -lz
diff --git a/builtin-prune.c b/builtin-prune.c
new file mode 100644
index 0000000..fc55b76
--- /dev/null
+++ b/builtin-prune.c
@@ -0,0 +1,259 @@
+#include "cache.h"
+#include "refs.h"
+#include "tag.h"
+#include "commit.h"
+#include "tree.h"
+#include "blob.h"
+#include "tree-walk.h"
+#include "diff.h"
+#include "revision.h"
+#include "builtin.h"
+#include "cache-tree.h"
+
+static const char prune_usage[] = "git prune [-n]";
+static int show_only = 0;
+static struct rev_info revs;
+
+static int prune_object(char *path, const char *filename, const unsigned char *sha1)
+{
+	if (show_only) {
+		printf("would prune %s/%s\n", path, filename);
+		return 0;
+	}
+	unlink(mkpath("%s/%s", path, filename));
+	rmdir(path);
+	return 0;
+}
+
+static int prune_dir(int i, char *path)
+{
+	DIR *dir = opendir(path);
+	struct dirent *de;
+
+	if (!dir)
+		return 0;
+
+	while ((de = readdir(dir)) != NULL) {
+		char name[100];
+		unsigned char sha1[20];
+		int len = strlen(de->d_name);
+
+		switch (len) {
+		case 2:
+			if (de->d_name[1] != '.')
+				break;
+		case 1:
+			if (de->d_name[0] != '.')
+				break;
+			continue;
+		case 38:
+			sprintf(name, "%02x", i);
+			memcpy(name+2, de->d_name, len+1);
+			if (get_sha1_hex(name, sha1) < 0)
+				break;
+
+			/*
+			 * Do we know about this object?
+			 * It must have been reachable
+			 */
+			if (lookup_object(sha1))
+				continue;
+
+			prune_object(path, de->d_name, sha1);
+			continue;
+		}
+		fprintf(stderr, "bad sha1 file: %s/%s\n", path, de->d_name);
+	}
+	closedir(dir);
+	return 0;
+}
+
+static void prune_object_dir(const char *path)
+{
+	int i;
+	for (i = 0; i < 256; i++) {
+		static char dir[4096];
+		sprintf(dir, "%s/%02x", path, i);
+		prune_dir(i, dir);
+	}
+}
+
+static void process_blob(struct blob *blob,
+			 struct object_array *p,
+			 struct name_path *path,
+			 const char *name)
+{
+	struct object *obj = &blob->object;
+
+	if (obj->flags & SEEN)
+		return;
+	obj->flags |= SEEN;
+	/* Nothing to do, really .. The blob lookup was the important part */
+}
+
+static void process_tree(struct tree *tree,
+			 struct object_array *p,
+			 struct name_path *path,
+			 const char *name)
+{
+	struct object *obj = &tree->object;
+	struct tree_desc desc;
+	struct name_entry entry;
+	struct name_path me;
+
+	if (obj->flags & SEEN)
+		return;
+	obj->flags |= SEEN;
+	if (parse_tree(tree) < 0)
+		die("bad tree object %s", sha1_to_hex(obj->sha1));
+	name = strdup(name);
+	add_object(obj, p, path, name);
+	me.up = path;
+	me.elem = name;
+	me.elem_len = strlen(name);
+
+	desc.buf = tree->buffer;
+	desc.size = tree->size;
+
+	while (tree_entry(&desc, &entry)) {
+		if (S_ISDIR(entry.mode))
+			process_tree(lookup_tree(entry.sha1), p, &me, entry.path);
+		else
+			process_blob(lookup_blob(entry.sha1), p, &me, entry.path);
+	}
+	free(tree->buffer);
+	tree->buffer = NULL;
+}
+
+static void process_tag(struct tag *tag, struct object_array *p, const char *name)
+{
+	struct object *obj = &tag->object;
+	struct name_path me;
+
+	if (obj->flags & SEEN)
+		return;
+	obj->flags |= SEEN;
+
+	me.up = NULL;
+	me.elem = "tag:/";
+	me.elem_len = 5;
+
+	if (parse_tag(tag) < 0)
+		die("bad tag object %s", sha1_to_hex(obj->sha1));
+	add_object(tag->tagged, p, NULL, name);
+}
+
+static void walk_commit_list(struct rev_info *revs)
+{
+	int i;
+	struct commit *commit;
+	struct object_array objects = { 0, 0, NULL };
+
+	/* Walk all commits, process their trees */
+	while ((commit = get_revision(revs)) != NULL)
+		process_tree(commit->tree, &objects, NULL, "");
+
+	/* Then walk all the pending objects, recursively processing them too */
+	for (i = 0; i < revs->pending.nr; i++) {
+		struct object_array_entry *pending = revs->pending.objects + i;
+		struct object *obj = pending->item;
+		const char *name = pending->name;
+		if (obj->type == TYPE_TAG) {
+			process_tag((struct tag *) obj, &objects, name);
+			continue;
+		}
+		if (obj->type == TYPE_TREE) {
+			process_tree((struct tree *)obj, &objects, NULL, name);
+			continue;
+		}
+		if (obj->type == TYPE_BLOB) {
+			process_blob((struct blob *)obj, &objects, NULL, name);
+			continue;
+		}
+		die("unknown pending object %s (%s)", sha1_to_hex(obj->sha1), name);
+	}
+}
+
+static int add_one_ref(const char *path, const unsigned char *sha1)
+{
+	struct object *object = parse_object(sha1);
+	if (!object)
+		die("bad object ref: %s:%s", path, sha1_to_hex(sha1));
+	add_pending_object(&revs, object, "");
+	return 0;        
+}
+
+static void add_one_tree(const unsigned char *sha1)
+{
+	struct tree *tree = lookup_tree(sha1);
+	add_pending_object(&revs, &tree->object, "");
+}
+
+static void add_cache_tree(struct cache_tree *it)
+{
+	int i;
+
+	if (it->entry_count >= 0)
+		add_one_tree(it->sha1);
+	for (i = 0; i < it->subtree_nr; i++)
+		add_cache_tree(it->down[i]->cache_tree);
+}
+
+static void add_cache_refs(void)
+{
+	int i;
+
+ 	read_cache();
+	for (i = 0; i < active_nr; i++) {
+		lookup_blob(active_cache[i]->sha1);
+		/*
+		 * We could add the blobs to the pending list, but quite
+		 * frankly, we don't care. Once we've looked them up, and
+		 * added them as objects, we've really done everything 
+		 * there is to do for a blob
+		 */
+	}
+	if (active_cache_tree)
+		add_cache_tree(active_cache_tree);
+}
+
+int cmd_prune(int argc, const char **argv, char **envp)
+{
+	int i;
+
+	for (i = 1; i < argc; i++) {
+		const char *arg = argv[i];
+		if (!strcmp(arg, "-n")) {
+			show_only = 1;
+			continue;
+		}
+		usage(prune_usage);
+	}
+
+	/*
+	 * Set up revision parsing, and mark us as being interested
+	 * in all object types, not just commits.
+	 */
+	init_revisions(&revs);
+	revs.tag_objects = 1;
+	revs.blob_objects = 1;
+	revs.tree_objects = 1;
+
+	/* Add all external refs */
+	for_each_ref(add_one_ref);
+
+	/* Add all refs from the index file */
+	add_cache_refs();
+
+	/*
+	 * Set up the revision walk - this will move all commits
+	 * from the pending list to the commit walking list.
+	 */
+	prepare_revision_walk(&revs);
+
+	walk_commit_list(&revs);
+
+	prune_object_dir(get_object_directory());
+
+	return 0;
+}
diff --git a/builtin.h b/builtin.h
index d9e5483..5339d86 100644
--- a/builtin.h
+++ b/builtin.h
@@ -25,6 +25,8 @@ extern int cmd_diff(int argc, const char
 extern int cmd_format_patch(int argc, const char **argv, char **envp);
 extern int cmd_count_objects(int argc, const char **argv, char **envp);
 
+extern int cmd_prune(int argc, const char **argv, char **envp);
+
 extern int cmd_push(int argc, const char **argv, char **envp);
 extern int cmd_grep(int argc, const char **argv, char **envp);
 extern int cmd_rm(int argc, const char **argv, char **envp);
diff --git a/git-prune.sh b/git-prune.sh
deleted file mode 100755
index c5a5d29..0000000
--- a/git-prune.sh
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/bin/sh
-
-USAGE='[-n] [--] [<head>...]'
-. git-sh-setup
-
-dryrun=
-echo=
-while case "$#" in 0) break ;; esac
-do
-    case "$1" in
-    -n) dryrun=-n echo=echo ;;
-    --) break ;;
-    -*) usage ;;
-    *)  break ;;
-    esac
-    shift;
-done
-
-sync
-case "$#" in
-0) git-fsck-objects --full --cache --unreachable ;;
-*) git-fsck-objects --full --cache --unreachable $(git-rev-parse --all) "$@" ;;
-esac |
-
-sed -ne '/unreachable /{
-    s/unreachable [^ ][^ ]* //
-    s|\(..\)|\1/|p
-}' | {
-	cd "$GIT_OBJECT_DIRECTORY" || exit
-	xargs $echo rm -f
-	rmdir 2>/dev/null [0-9a-f][0-9a-f]
-}
-
-git-prune-packed $dryrun
-
-if redundant=$(git-pack-redundant --all 2>/dev/null) && test "" != "$redundant"
-then
-	if test "" = "$dryrun"
-	then
-		echo "$redundant" | xargs rm -f
-	else
-		echo rm -f "$redundant"
-	fi
-fi
diff --git a/git.c b/git.c
index 2567301..16e37e5 100644
--- a/git.c
+++ b/git.c
@@ -188,7 +188,8 @@ static void handle_internal_command(int 
 		{ "stripspace", cmd_stripspace },
 		{ "update-index", cmd_update_index },
 		{ "update-ref", cmd_update_ref },
-		{ "fmt-merge-msg", cmd_fmt_merge_msg }
+		{ "fmt-merge-msg", cmd_fmt_merge_msg },
+		{ "prune", cmd_prune },
 	};
 	int i;
 

^ permalink raw reply related

* Re: Does Git run on Windows ?
From: Aaron Gray @ 2006-07-06 17:18 UTC (permalink / raw)
  To: Git Mailing List
In-Reply-To: <46a038f90607051956w72c5e662g72feb242795e61c4@mail.gmail.com>

>> This maybe the crunch and reason to use CVS for now :(?)
>
> If you are only supporting some users on Windows, you may be able to
> use git-cvsserver for them. Looks like a cvsserver but it is a GIT
> repository ;-)

Thanks. This looks like the best option. Run Git, GitWeb, and git-cvsserver
on our Linux server. Allowing Windows users to connect via CVS and GitWeb.
Nice, looks like the right solution, best of both worlds.

Running Cygwin, Perl, and Python is not really something I could expect of
Windows programmers.

Many thanks,

Aaron

^ permalink raw reply

* [ANNOUNCE] ClearCase UCM -> git converter
From: Rutger Nijlunsing @ 2006-07-06 17:36 UTC (permalink / raw)
  To: git

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

Hi,

Find attached a ClearCase UCM -> git converter.

While UCM does have branches and so on, this importer imports one
stream. Since UCM is somewhat like an expensive CVS, it is quite
difficult to retrieve more information from UCM in a useful way: the
concept are just too poluted.

Features:
  - Author files support to map ClearCase usernames to git user names
  - Incrementally import one ClearCase UCM stream into git.
    Just rerun the script when new baselines were created.
  - Handles composite baselines
  - Auto-detection of VOB, stream, rules to load, .. as much
    as possible.
  - Auto repack after a lot of objects have been generated
  - Should be able to pick up where it left after an interruption.

HOWEVER, it is Windows only currently since I don't have a cleartool
unix client. It should not be too hard to convert though, since it
uses the normal 'cleartool' command line client to retrieve all
information.

Usage:

Just have your stream-to-be-converted running at, say, m:\mystream_int
(most likely an integration stream), and say something like:

	git-ucmimport m:\mystream_int c:\mystream_git

...and hopefully it should detect all configuration items and start
converting.

Can also be found at http://www.wingding.demon.nl .

Rutger.

-- 
Rutger Nijlunsing ---------------------------------- eludias ed dse.nl
never attribute to a conspiracy which can be explained by incompetence
----------------------------------------------------------------------

[-- Attachment #2: git-ucmimport.rb --]
[-- Type: text/plain, Size: 20028 bytes --]

#!/usr/bin/env ruby

# ClearCase UCM -> git importer.
#
# Imports the baselines of _one_ stream into a Git repository.
#
# Features:
#   - Author files support to map ClearCase usernames to git user names
#   - Incrementally import one ClearCase UCM stream into git.
#     Just rerun the script when new baselines were created.
#   - Handles composite baselines
#   - Auto-detection of VOB, stream, rules to load, .. as much
#     as possible.
#   - Auto repack after a lot of objects have been generated
#   - Should be able to pick up where it left after an interrruption.
#
# Assumptions:
#   - Works on Windows for me(TM). Not tested on Unix.
#
# Discussion:
# Importing the whole tree of streams (branches) of UCM into git is
# next to impossible. UCM has the concepts of 'activities' which
# contain versions of changed files, and a set of activities is
# delivered as a changeset. So far so good. However, activities may be
# reused (even over changeset boundary) and may be interleaved with
# each other. This makes it infeasible to map activities or changesets
# on git commits, which is a much nicer concept.
#
# 2006 Rutger Nijlunsing <git-ucmimport@tux.tmfweb.nl>

############################## Config documentation.
# Don't change those; just use the command line switches to set them.
# Section below is mainly for documentation purposes. ;)

# ClearCase: Directory with existing Dynamic view on integration
# stream to import. Probably a subdirectory on M:\, or under /view
$int_view_dir = ""

# Location of snapshot view on substream of integration stream. We are
# going to rebase this stream to a newer version in int_view, and then
# check in the result.
$sub_view_dir = ""

# Baseline in parent stream to start importing at if the destination
# snapshot view does not exist.
# If empty, takes first baseline.
# Use 'cleartool lsbl' in stream directory to get a list.
first_baseline = ""

# Subdirectory of $sub_view_dir to generate git repository at.  Only
# files in this directory or lower are added. This can be used when a
# common subdirectory is always added to the paths (which is common in
# ClearCase). If unsure, leave empty.
$sub_root = ""

# Filename with author mapping from ClearCase to Git. Leave empty ("")
# to have no mapping and use the ClearCase names.
# Format of file is lines containing:
#   'cc_author_name=Real Name <email@domain.com>'
$ucm_authors_file = ""

# Server Storage Location for the view storage directory.
# This is the same as can be found in the GUI:
#   ClearCase Explorer -> Join Project -> Next -> Next -> Next ->
#     Advanced Options -> [x] Use server storage location,
# and then the 'name' column of that table.
# Use empty string ("") for default.
stgloc = "ADVIEWS"

##############################

# Include required standard Ruby libraries
require 'find'
require 'fileutils'
require 'time'
require 'optparse'
require 'ostruct'

$VERBOSE = true
$verbose = true

def die(*txt); puts txt.flatten.join("\n"); exit 1; end

def read_ucm_authors(authors_filename)
  users = {}
  begin
    IO.foreach(authors_filename) { |line|
      if line =~ %r{^(\S+?)\s*=\s*(.+?)\s*<(.+)>\s*$}
        user, name, email = $1, $2, $3
        users[user] = [name, email]
      end
    }
  rescue Errno::ENOENT, Errno::EACCES
    die("Could not read #{authors_filename}: #{$!}")
  end
  if $verbose
    puts "Read #{users.size} authors from #{authors_filename}"
  end
  return users
end

def write_ucm_authors(users, authors_filename)
  begin
    File.open(authors_filename, "wb") { |io|
      users.keys.sort.each { |user|
        io.puts "#{user} = #{users[user][0]} <#{users[user][1]}>"
      }
    }
    if $verbose
      puts "Wrote #{users.size} authors to #{authors_filename}"
    end
  rescue Errno::EACCES
    die("Could not write #{authors_filename}: #{$!}")
  end
end

def read_write_ucm_authors
  # Maping from ClearCase author name to full name and email
  default_ucm_authors_file = "#{$git_dir}/ucm-authors"
  $users = File.readable?(default_ucm_authors_file) ?
  read_ucm_authors(default_ucm_authors_file) : {}
  # If authors file explicitly given, add
  if $ucm_authors_file && $ucm_authors_file != ""
    users_to_add = read_ucm_authors($ucm_authors_file)
    if users_to_add.size > 0
      $users.merge!(users_to_add) 
      write_ucm_authors($users, default_ucm_authors_file)
    end
  end
end

module Shell
  # Escape string string so that it is parsed to the string itself
  # Compare to Regexp.escape .
  def self.escape(string)
    (string !~ %r{[ "]}i && string != "") ? 
      string : '"' + string.gsub(%r{(["])}i, '\\\\\1') + '"'
  end if not defined? self.escape
end

# Run 'cleartool' and filter the output.
def system_filter_output(cmd, may_fail)
  no_merge_required = false
  hijacked = []
  p cmd
  File.popen("#{cmd} 2>&1", "rb") { |io|
    while line = io.gets
      line = line.rstrip
      next if line =~ %r{^[.]*$}
      next if line =~ %r{^End dir }
      next if line =~ %r{^Processing dir }
      next if line =~ %r{^Done loading }
      next if line =~ %r{^Log has been written to }
      next if line =~ %r{^Making dir } # Only interested in files...
      line = line.
	sub(%r{^Loading }, "+ ").
	sub(%r{^Unloaded }, "- ")
      no_merge_required = true if line =~ %r{^No versions require merging}
      if line =~ %r{^Keeping hijacked object "(.*)"}
	hijacked << $1
      else
	raise if line =~ %r{hijacked}
      end
      puts line
    end
  }
  # Some hijacked files might be left. Update them manually
  hijacked.each { |f|
    puts "Unhijacking #{f}"
    safe_system("cleartool update -overwrite #{Shell.escape(f)}")
  }
  ok = no_merge_required
  if !ok && !may_fail
    die(
	"!!! View at #{Dir.pwd} is not clean.",
	"!!! No checkout out files, hijacked files etc. may be present.",
	"!!! Restore the view (undo hijacking, undo checkouts etc.) and retry."
    )
  end
  return ok
end

def skip(*cmd); puts "Skipping #{cmd.inspect}"; end

# Run a command with its arguments.
# When cmd is an array, a boolean indicates whether the next argument should
# be emitted or not.
def safe_system(*cmd)
  emit = true
  cmdline = [cmd].flatten.collect { |arg|
    if (arg == true) || (arg == false)
      emit = arg
      arg = nil
    else
      arg = nil if !emit
      emit = true
    end
    arg.to_s
  }.join(" ")
  puts cmdline if $verbose
  system(cmdline)
  if $? != 0
    puts cmdline if !$verbose
    puts "!!! Command returned non-zero exit code: #{$?}"
    puts "!!! Working dir: #{Dir.pwd}"
    exit $?
  end
end

def safe_popen(cmd, mode = "w+", &callback)
  puts "|" + cmd if $verbose
  res = IO.popen(cmd, mode, &callback)
  if $? != 0
    puts cmd if !$verbose
    puts "!!! Command returned non-zero exit code: #{$?}"
    puts "!!! Working dir: #{Dir.pwd}"
    exit $?
  end
  return res
end

# Returns all rules loaded in the current directory
def read_loaded_rules
  rules = {}
  File.popen("cleartool catcs", "rb") { |io|
    while line = io.gets
      rules[$1] = true if line =~ %r{^element "\[[0-9a-f]{32}=(.*)\].*\" }
    end
  }
  rules = rules.keys
  return rules
end

class Activity
  attr_accessor :id, :author, :comment

  def is_activity; @id !~ %r{^(deliver|rebase)\.}; end

  def initialize(id, author, comment)
    @id = id
    @author = author
    @comment = comment
  end

  def hash; @id.hash; end
  def eql?(other); @id == other.id; end
end

# A baseline of a stream
class Baseline
  attr_reader :name		# Name of baseline
  attr_reader :date		# Date of creation of baseline
  attr_reader :author		# User who created the baseline
  attr_reader :comment
  attr_reader :children		# For composite baselines
  attr_reader :parent		# For non-composite baselines
  attr_accessor :component	# String

  def initialize(name, date, author, comment)
    @name = name
    @date = date
    @author = author
    @comment = comment
    @children = []
    @parent = nil
  end
  
  def set_parent(b); @parent = b; b.add_child(self); end
  def add_child(baseline); @children << baseline; end

  # Returns self and all children (recursively)
  def children_recursive
    res = [self]
    children.each { |c| res += c.children_recursive }
    return res
  end
end

# Make sure .git exists and save the state
def git_init_db
  Dir.chdir($git_root)
  if !File.directory?($git_dir)
    puts "\n=== Creating initial git repository at #{$git_root}"
    safe_system("git init-db")
    if !File.directory?($git_dir)
      die("!!! Could not create git repo at #{$git_root}")
    end
  end
  save_state
end

def git_commit(baseline, msg)
  Dir.chdir($sub_view_dir)
  puts "\n=== Removing ClearCase left-over files..."
  Find.find(".") { |elem|
    if elem =~ %r{\.(contrib|keep|renamed|unloaded|loading|mkelem)(\.\d+)?$} ||
	elem =~ %r{\.(updt|stackdump)$}
      puts "Removing #{elem}"
      FileUtils.rm_rf(elem)
    end
  }

  Dir.chdir($git_root)
  puts "\n=== Adding files to git"
  safe_system("git add .")

  author = baseline.author
  email = nil
  author, email = $users[author] if $users[author]
  author ||= "unknown"
  email ||= "unknown"

  ENV['GIT_AUTHOR_NAME'] = ENV['GIT_COMMITTER_NAME'] = author
  ENV['GIT_AUTHOR_EMAIL'] = ENV['GIT_COMMITTER_EMAIL'] = email
  date = baseline.date
  if date
    puts "Date: #{date}"
    ENV['GIT_AUTHOR_DATE'] = ENV['GIT_COMMITTER_DATE'] =
      date.strftime("+0000 %Y-%m-%d %H:%M:%S")
  else
    ENV.delete('GIT_AUTHOR_DATE')
    ENV.delete('GIT_COMMITTER_DATE')
  end

  puts "\n=== Committing new version to git"
  puts "Commit message:"
  puts msg
  # 'git commit' might fail if no data is added, so no safe_popen()
  cmd = "git commit --no-verify -F - --all"
  File.popen(cmd, "wb") { |io|
    io.print msg
  }

  puts "\n=== Tagging baseline in git"
  system("git tag -f #{baseline.name}")
end

$state_version = "20060706"

# Load state. Returns true in case of succes.
def load_state
  begin
    state = File.open($state, "rb") { |io| Marshal.load(io) }
    if state.version != $state_version
      die(
        "!!! Previous state has different version (#{state.version}) ",
        "!!! than this git-ucmimport version (#{$state_version})"
      )
    else
      $int_view_dir = state.int_view_dir
      $sub_view_dir = state.sub_view_dir
      $sub_root = state.sub_root
      return true
    end
  rescue Errno::ENOENT
  end
  return false
end

def save_state
  File.open($state + ".new", "wb") { |io|
    state = OpenStruct.new
    state.version = $state_version
    state.int_view_dir = $int_view_dir
    state.sub_view_dir = $sub_view_dir
    state.sub_root = $sub_root
    io.write(Marshal.dump(state))
  }
  # Rename atomically new state into _the_ state
  File.rename($state + ".new", $state)
end

######################################## Start of main

# Make sure Cygwin is in front of path. Otherwise we might fail
# if other Unix toolkits (like NutCracker) are simultanously installed.
ENV['PATH'] = "c:\\cygwin\\bin;" + ENV['PATH']

$state = ".git/git-ucmimport.state"
state_loaded = false
state_loaded ||= load_state if File.exists?($state)

puts "ClearCase UCM -> git importer"
puts "(c)2006 R. Nijlunsing <git-ucmimport@tux.tmfweb.nl>"
puts "License: LGPL."
puts
$opts = OptionParser.new
$opts.banner = %q{Usage:
  git-ucmimport [dynamic view to import] [dir to export to]
     For the initial conversion.

  git-ucmimport
     From the git repository to incrementally convert.

Example:
  git-ucmimport --authors-file c:\\temp\\authors m:\\jparser_int c:\\jparser_git
  ...to import the stream of view 'jparser_int' which is started at
  m:\\jparser_int into newly-generated stream, view and directory at
  c:\\jparser_git .  c:\\temp\\authors contains the usernames mapping.
  c:\\jparser_git will both be a UCM view as well as an git repo, but will
  be read-only! So to develop against the converted archive, use 'git clone'.

  To convert the view incrementally, go to the root of the git repository
  (which contains the '.git' directory), and call 'git-ucmimport' without
  any parameters. In this example case that would be from c:\\jparser_git .

  For more information regarding the options, read the top of this script.

}
$opts.on("--help", "-h", "This usage") { puts $opts; exit 1 }
$opts.on(
  "--authors-file FILE", "-A",
  "Add file with mapping from ClearCase user", "to git author"
) { |f| $ucm_authors_file = File.expand_path(f) }
$opts.on("\nOptions for first-time import:")
$opts.on(
  "--stgloc LOCATION",
  "Server Storage Location for the view",
  "storage directory [chosen by UCM]"
) { |s| stgloc = s }
$opts.on(
  "--first-baseline BASELINE",
  "Start importing at given baseline", "[oldest baseline]"
) { |bl| first_baseline = bl }
$opts.on(
  "--root DIRINREPO",
  "Make given directory the root of the git", "repository"
) { |sr| $sub_root = sr }
$opts.on("")
begin
  $opts.parse!(ARGV)
rescue OptionParser::InvalidOption
  die("!!! Invalid option", $opts)
end

if !state_loaded
  if ARGV.size != 2
    puts $opts
    die("!!! Need at least the import and export directory")
  end
  $int_view_dir, $sub_view_dir = ARGV
end

# Git: Location of git archive
$git_root = $sub_view_dir
$git_root += "/" + $sub_root if $sub_root && $sub_root != ""
$git_dir = "#{$git_root}/.git"
$state = "#{$git_dir}/git-ucmimport.state"

puts "UCM Source:      Dynamic view at \"#{$int_view_dir}\""
puts "UCM Mirror repo: Snapshot view at \"#{$sub_view_dir}\""
puts "git repo:        At \"#{$git_root}\""
puts "Start baseline:  At #{first_baseline}" if first_baseline && first_baseline != ""
puts

# Check for existance of git in $PATH
safe_system("git version")

if !File.directory?($int_view_dir)
  die(
      "!!! Cannot find \"#{$int_view_dir}\",",
      "!!! which should contain integration view directory.",
      "!!! Did you start your view?"
  )
end

puts "\n=== Retrieving all current baselines to import"
Dir.chdir($int_view_dir)
vob = nil			# String: VOB
int_stream = nil		# String: name of stream
baselines = {}			# From name to Baseline
baseline = nil
#File.open("c:\\temp\\lsbl.memberof", "rb") { |io|
File.popen("cleartool lsbl -member_of", "rb") { |io|
  while line = io.gets
    line = line.rstrip
    if line =~ %r{^([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+\"(.*)\"$}
      # New baseline found
      date, name, author, comment = $1, $2, $3, $4
      $VERBOSE = false		# Time.parse warns about year...
      baseline = Baseline.new(name, Time.parse(date), author, comment)
      $VERBOSE = true
      $stderr.print "." if baselines.size % 10 == 0
      baselines[name] = baseline
    elsif line =~ %r{^  component: ([^ @]+)@([^ ]+)$}
      baseline.component = $1
      vob = $2
    elsif line =~ %r{^  stream: ([^ @]+)@([^ ]+)$}
      int_stream = $1
    elsif line =~ %r{^    ([^ @]+)@([^ ]+) \(.*\)}
      # 'member of:' line    
      baseline.set_parent(baselines[$1])
    end
  end
}
$stderr.puts
# We only need to keep the root of all composite baselines sorted on time.
baselines =
  baselines.keys.
  find_all { |n| baselines[n].parent.nil? }. # Only keep root baselines
  collect { |n| baselines[n] }.
  sort_by { |b| b.date }	# Sort them on date
puts "Found #{baselines.size} (composite) baselines."

components = baselines.collect { |b| b.component }.uniq
if components.size != 1
  die(
      "!!! Not all baselines belong to the same component!",
      "!!! Too afraid to continue.",
      "!!! Components found: #{components.inspect}"
  )
end

if !first_baseline || first_baseline == ""
  first_baseline = baselines[0].name
end
first_baseline_idx = nil
baselines.each_with_index { |b, idx|
  first_baseline_idx = idx if b.name == first_baseline
}
if !first_baseline_idx
  die("!!! Could not find first_baseline with name \"#{first_baseline}\"")
end

# Create destination stream if needed
if !File.exist?($sub_view_dir)
  puts "\n=== Reading all rules loaded in stream to import"
  Dir.chdir($int_view_dir)
  loaded_rules = read_loaded_rules
  puts "Currently loaded rules: #{loaded_rules.inspect}"

  sub_stream = File.basename($sub_view_dir)
  puts "\n=== Creating read-only stream '#{sub_stream}'"
  safe_system(
    "cleartool mkstream",
    "-in stream:#{int_stream}@#{vob}",
    "-readonly",
    "-baseline baseline:#{first_baseline}",
    "#{sub_stream}@#{vob}"
  )

  Dir.chdir(File.dirname($sub_view_dir))
  puts "\n=== Creating snapshot view at #{$sub_view_dir}"
  safe_system(
    "cleartool mkview",
    "-snapshot -ptime",
    "-tag #{sub_stream}",
    "-stream #{sub_stream}@#{vob}",
    stgloc && stgloc != "", "-stgloc #{stgloc}",
    sub_stream
  )
  $sub_view_dir = Dir.pwd + "/" + sub_stream

  puts "\n=== Load rules and update view"
  Dir.chdir($sub_view_dir)
  loaded_rules.each { |rule|
    system_filter_output("cleartool update -overwrite -add_loadrules #{rule[1..-1]}", true)
  }

  git_init_db
  read_write_ucm_authors
  git_commit(baselines[first_baseline_idx], "Initial commit")
else
  read_write_ucm_authors
  puts "\n=== Updating view to be sure snapshot view matches UCM contents"
  Dir.chdir($sub_view_dir)
  system_filter_output("cleartool update -overwrite", true)
end

git_init_db

puts "\n=== Finding current baseline"
Dir.chdir($sub_view_dir)
cmd = "cleartool lsstream -long -obsolete"
p cmd
lsstream = `#{cmd}`
if lsstream !~ %r{^\s+foundation baselines:\s+([^@]+)@}m
  puts lsstream
  die("!!! Could not retrieve current baseline")
end
current_baseline = $1
puts "Current baseline: #{current_baseline}"
if current_baseline =~ %r{INITIAL$}
  die(
      "!!! Current baseline should be newer than INITIAL",
      "!!! Please rebase #{$sub_view_dir} to a newer baseline."
  )
end

current_baseline_idx = nil
baselines.each_with_index { |b, idx|
  current_baseline_idx = idx if b.name == current_baseline
}

if !current_baseline_idx
  die(
    "!!! Did not find our current baseline in Integration Stream.",
    "!!! Make sure that stream of view #{$sub_view_dir} is really",
    "!!! a child of stream of view #{$int_view_dir}"
  )
end

baselines_to_commit = baselines[current_baseline_idx + 1 .. -1]

if baselines_to_commit.empty?
  puts "\nNothing to do, already up-to-date."
  exit 0
end

puts "Got #{baselines_to_commit.size} baselines to convert to git commits"

puts "\n=== Abort previous rebase attempt (if any)."
Dir.chdir($sub_view_dir)
system_filter_output("cleartool rebase -cancel -force", true)

baselines_to_commit.each_with_index { |baseline, idx|
  # If a lot of loose objects in Git, repack.
  # Counts numbers of 'objects' directories, 256 max.
  Dir.chdir($git_root)
  if Dir[".git/objects/??"].size >= 253
    puts "\n=== Repacking."
    # To err is non-fatal, so no safe_system is needed.
    system("git repack -d")
  end

  puts
  puts "\n=== [#{idx + 1}/#{baselines_to_commit.size}]"
  puts "=== Reading effect of rebasing of #{$sub_view_dir} to baseline #{baseline.name}"
  Dir.chdir($sub_view_dir)
  activities = []

  # In the composite baseline, we get little information about the
  # activities we bring in. Therefore, ask all contained baselines
  # about the activities it contains.
  baseline_names = baseline.
    children_recursive.collect { |cbl| cbl.name }.join(",")
  cmd = "cleartool rebase -preview -baseline #{baseline_names}"
  safe_popen(cmd, "rb") { |io|
    while line = io.gets
      line = line.rstrip
      if line =~ %r{^\tactivity:([^\t]*)\t([^\t]*)\t\"(.*)\"$}
	id, author, comment = $1, $2, $3
	activities << Activity.new(id, author, comment)
      end
    end
  }
  activities = activities.uniq

  if activities.empty?
    puts "? New baseline contains no new activities, skipping"
    next
  end

  puts "Will retrieve activities:"
  activities.each { |a|
    puts "  #{a.author} #{a.id}"
  }

  system_filter_output("cleartool rebase -qall -baseline #{baseline.name}", false)

  subject =
    activities.find_all { |a| a.is_activity }.
    collect { |a| a.comment }.join(" / ") + "\n\n"
  msg = subject +
    activities.collect { |a| "#{a.comment}\nActivity: #{a.id}\n\n" }.join("")
  git_commit(baseline, msg)

  puts "\n=== Completing ClearCase UCM rebase."
  system_filter_output("cleartool rebase -complete", true)
}

^ permalink raw reply

* Re: comparing file contents in is_exact_match?
From: Martin Waitz @ 2006-07-06 17:55 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vwtar89wy.fsf@assigned-by-dhcp.cox.net>

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

hoi :)

On Thu, Jul 06, 2006 at 12:33:33AM -0700, Junio C Hamano wrote:
> Although I am not sure how much this would help with a regular
> workload, maybe something like this untested patch might help
> your situation?

works perfectly!
Thanks!

-- 
Martin Waitz

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

^ permalink raw reply

* Re: qgit idea: marking refs (heads and tags)
From: Marco Costalba @ 2006-07-06 18:39 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git
In-Reply-To: <e8dnst$pvh$1@sea.gmane.org>

On 7/4/06, Jakub Narebski <jnareb@gmail.com> wrote:
>
> >> And also somewhat (but to much lesser extent) showing explicitely sha1-ids
> >> for commit, parents, tree, referenced object (in tag), to copy'n'paste to
> >> shell.
> >
> > Something as a typical browser "copy selected link" context menu entry?
>
> Yes, "copy sha1 of selected link" would be nice.
>

Patch pushed to public repo (git.kernel.org/pub/scm/qgit/qgit.git)

   Marco

^ permalink raw reply

* Moving a topic branch forward: rebase vs. resolve
From: Marc Singer @ 2006-07-06 21:10 UTC (permalink / raw)
  To: Git Mailing List

In moving a topic branch forward from about 2.6.16 to 2.6.18-rc1, I'm
finding little solace in either rebase or resolve.


  REBASE

Rebase is an attractive method as it preserves the change history,
though in the end the only interesting bits are those that are merged
with master.  


  --1---2----3---4   master
     \
      --A--B--C      topic


In rebasing ABC at 4, it looks like git is applying each patch in
turn.  While this is strictly correct, it can make for a tedious merge
if both A and C modify the same piece of code *and* if revision 2
makes both A and C merge with conflicts.  The result was an exhausting
march through the change sets.


  RESOLVE

So, I tried resolve which I would expect to apply the other direction,
merging 234 onto C.  git-resolve finishes in a single pass leaving
conflict markers in a number of files.  However, some of these are
unexpected, conflicts in files that I've not and which I'd expect to
merge cleanly.  For example

    diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
    index 2975291..fea24ba 100644
    --- a/Documentation/DocBook/Makefile
    +++ b/Documentation/DocBook/Makefile
    @@ -2,15 +2,21 @@ ###
     # This makefile is used to generate the kernel documentation,
     # primarily based on in-line comments in various source files.
     # See Documentation/kernel-doc-nano-HOWTO.txt for instruction in how
    -# to ducument the SRC - and how to read it.
    +# to document the SRC - and how to read it.
     # To add a new book the only step required is to add the book to the
     # list of DOCBOOKS.

     DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.xml \
		kernel-hacking.xml kernel-locking.xml deviceiobook.xml \
		procfs-guide.xml writing_usb_driver.xml \
    +<<<<<<< .merge_file_arWYZk
		kernel-api.xml journal-api.xml lsm.xml usb.xml \
		gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml
    +=======
    +           kernel-api.xml journal-api.xml lsm.xml usb.xml \
    +           gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \
    +           genericirq.xml
    +>>>>>>> .merge_file_G8cSmh


We have a spelling fix and the addition of genericirq.xml.  What would
cause these sorts of conflicts?  Is there someting I can do to
eliminate them or resolve them properly?

Cheers.

^ permalink raw reply

* Re: Moving a topic branch forward: rebase vs. resolve
From: Linus Torvalds @ 2006-07-06 21:24 UTC (permalink / raw)
  To: Marc Singer; +Cc: Git Mailing List
In-Reply-To: <20060706211008.GA6566@buici.com>



On Thu, 6 Jul 2006, Marc Singer wrote:
> 
> So, I tried resolve which I would expect to apply the other direction,
> merging 234 onto C.  git-resolve finishes in a single pass leaving
> conflict markers in a number of files.  However, some of these are
> unexpected, conflicts in files that I've not and which I'd expect to
> merge cleanly.  For example
> 
>     diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
>     index 2975291..fea24ba 100644
>     --- a/Documentation/DocBook/Makefile
>     +++ b/Documentation/DocBook/Makefile
>     @@ -2,15 +2,21 @@ ###
>      # This makefile is used to generate the kernel documentation,
>      # primarily based on in-line comments in various source files.
>      # See Documentation/kernel-doc-nano-HOWTO.txt for instruction in how
>     -# to ducument the SRC - and how to read it.
>     +# to document the SRC - and how to read it.
>      # To add a new book the only step required is to add the book to the
>      # list of DOCBOOKS.
> 
>      DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.xml \
> 		kernel-hacking.xml kernel-locking.xml deviceiobook.xml \
> 		procfs-guide.xml writing_usb_driver.xml \
>     +<<<<<<< .merge_file_arWYZk
> 		kernel-api.xml journal-api.xml lsm.xml usb.xml \
> 		gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml
>     +=======
>     +           kernel-api.xml journal-api.xml lsm.xml usb.xml \
>     +           gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \
>     +           genericirq.xml
>     +>>>>>>> .merge_file_G8cSmh
> 
> We have a spelling fix and the addition of genericirq.xml.  What would
> cause these sorts of conflicts?  Is there someting I can do to
> eliminate them or resolve them properly?

Well, the spelling fix was already merged properly. I can't tell why it 
thinks it conflicted on the addition of genericirq.xml, but it _looks_ 
like you may have done some whitespace changes. The merge result seems 
obvious (pick the second hunk, possibly editing the whitespace to match).

If you wonder why a merge clashes, and you want to see what both branches 
did, see the email thread a few days ago called "A note on merging 
conflicts" on how to efficiently and easily see what the changes were in 
both branches.

			Linus

^ permalink raw reply

* git-log output changed from 1.4.0 -> 1.4.1?
From: Robin Luckey @ 2006-07-06 21:51 UTC (permalink / raw)
  To: git

We use a custom script to generate reports based on the git-log
output. However, it appears that the output of git-log has changed in
1.4.1, and I have been unable to discover a set of flags to recreate
the log format to which I have become accustomed.

In git 1.4.0, the following command...

git log -r --root --abbrev=40 master

...would generate log entries like this...

commit 8db998464a3cc7f41728ac8bb59aee0f62e14aa8
Author: someone <someone>
Date:   Sun Aug 29 09:44:49 2004 +0000

    A comment goes here.

:100755 000000 56f5eb6c914c7ff6706dc3f8736a77d155cad93f
0000000000000000000000000000000000000000 D someapp/file1.c
:100755 000000 d7e0277fe15bfc11f75cbc535ecf1c5ee3d79baf
0000000000000000000000000000000000000000 D someapp/file2.c

Is there a way to generate this same format with git 1.4.1?

Thanks,
Robin

^ permalink raw reply

* Re: git-log output changed from 1.4.0 -> 1.4.1?
From: Johannes Schindelin @ 2006-07-06 21:56 UTC (permalink / raw)
  To: Robin Luckey; +Cc: git
In-Reply-To: <761519800607061451n9473ad4oa9e2781517ca9389@mail.gmail.com>

Hi,

On Thu, 6 Jul 2006, Robin Luckey wrote:

> In git 1.4.0, the following command...
> 
> git log -r --root --abbrev=40 master
> 
> ...would generate log entries like this...
> 
> commit 8db998464a3cc7f41728ac8bb59aee0f62e14aa8
> Author: someone <someone>
> Date:   Sun Aug 29 09:44:49 2004 +0000
> 
>    A comment goes here.
> 
> :100755 000000 56f5eb6c914c7ff6706dc3f8736a77d155cad93f
> 0000000000000000000000000000000000000000 D someapp/file1.c
> :100755 000000 d7e0277fe15bfc11f75cbc535ecf1c5ee3d79baf
> 0000000000000000000000000000000000000000 D someapp/file2.c
> 
> Is there a way to generate this same format with git 1.4.1?

I do not know about git 1.4.1, but with 'next' you can just add '--raw' to 
the command line, and it works.

Hth,
Dscho

^ permalink raw reply

* Re: git-log output changed from 1.4.0 -> 1.4.1?
From: Junio C Hamano @ 2006-07-06 21:58 UTC (permalink / raw)
  To: Robin Luckey; +Cc: git
In-Reply-To: <761519800607061451n9473ad4oa9e2781517ca9389@mail.gmail.com>

"Robin Luckey" <robinluckey@gmail.com> writes:

> In git 1.4.0, the following command...
>
> git log -r --root --abbrev=40 master

After Timo's diff options rewrite, -r does not seem to
automatically imply diff output anymore.  I personally think it
should.

In the meantime, "git log --raw -r ..." would give you want you
want, I think.

^ permalink raw reply

* Re: Re: git-log output changed from 1.4.0 -> 1.4.1?
From: Robin Luckey @ 2006-07-06 22:09 UTC (permalink / raw)
  To: git
In-Reply-To: <7vlkr65rbo.fsf@assigned-by-dhcp.cox.net>

> In the meantime, "git log --raw -r ..." would give you want you
> want, I think.

This did the trick! Thanks for the quick responses.

Robin

^ permalink raw reply

* [PATCH] Fix compilation
From: Johannes Schindelin @ 2006-07-06 23:21 UTC (permalink / raw)
  To: git, junkio


Without this, make 3.79.1 (Darwin) says

rm -f git-archimport git-archimport+
INSTLIBDIR=`make -C perl -s --no-print-directory instlibdir` && \
sed -e '1s|#!.*perl|#!/usr/bin/perl|1' \
    -e '2i\
        use lib (split(/:/, $ENV{GITPERLLIB} || '\'"$INSTLIBDIR"\''));' \
    -e 's|@@INSTLIBDIR@@|'"$INSTLIBDIR"'|g' \
    -e 's/@@GIT_VERSION@@/1.4.1.gb564-dirty/g' \
    git-archimport.perl >git-archimport+
sed: 1: "2i use lib (split(/:/,  ...": command i expects \ followed by text

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

---

	Note that this just fixes compilation, not the tests. All of
	a sudden, I have to install Scalar::Util, where things were
	fine before Git.pm.

	Note also, that this patch relies on the perl scripts not
	caring if an additional command is shifted into the 2nd line.
	I checked all of them, and they don't.

 Makefile |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -563,8 +563,7 @@ common-cmds.h: Documentation/git-*.txt
 	rm -f $@ $@+
 	INSTLIBDIR=`$(MAKE) -C perl -s --no-print-directory instlibdir` && \
 	sed -e '1s|#!.*perl|#!$(PERL_PATH_SQ)|1' \
-	    -e '2i\
-	        use lib (split(/:/, $$ENV{GITPERLLIB} || '\'"$$INSTLIBDIR"\''));' \
+	    -e "2s=^=use lib (split(/:/, \$$ENV{GITPERLLIB} || \'$$INSTLIBDIR\')); =g" \
 	    -e 's|@@INSTLIBDIR@@|'"$$INSTLIBDIR"'|g' \
 	    -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
 	    $@.perl >$@+

^ permalink raw reply

* Re: git-fetch per-repository speed issues
From: David Woodhouse @ 2006-07-06 23:36 UTC (permalink / raw)
  To: Keith Packard; +Cc: Git Mailing List
In-Reply-To: <1151949764.4723.51.camel@neko.keithp.com>

On Mon, 2006-07-03 at 11:02 -0700, Keith Packard wrote:
>  just uses ssh for everything. This slows down the connection process
> by several seconds.

Only if you forgot to use the 'control socket' support, which lets you
make a _single_ authenticated connection and re-use it for multiple
sessions.

http://david.woodhou.se/openssh-control.html has a couple of
improvements, but the basics are usable in upstream openssh.

-- 
dwmw2

^ permalink raw reply

* Re: [PATCH] Fix compilation
From: Junio C Hamano @ 2006-07-07  0:15 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: git
In-Reply-To: <Pine.LNX.4.63.0607070120590.29667@wbgn013.biozentrum.uni-wuerzburg.de>

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

> Without this, make 3.79.1 (Darwin) says
>
> rm -f git-archimport git-archimport+
> INSTLIBDIR=`make -C perl -s --no-print-directory instlibdir` && \
> sed -e '1s|#!.*perl|#!/usr/bin/perl|1' \
>     -e '2i\
>         use lib (split(/:/, $ENV{GITPERLLIB} || '\'"$INSTLIBDIR"\''));' \
>     -e 's|@@INSTLIBDIR@@|'"$INSTLIBDIR"'|g' \
>     -e 's/@@GIT_VERSION@@/1.4.1.gb564-dirty/g' \
>     git-archimport.perl >git-archimport+
> sed: 1: "2i use lib (split(/:/,  ...": command i expects \ followed by text
>
> Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>

Traditionally 'i' and 'a' command to sed has been unfriendly
with make, primarily because different make implementations did
unexpected things to backslashes at the end of lines.

For portability I would even suggest making that command into a
separate helper shell script, and call that from the Makefile.

> 	Note that this just fixes compilation, not the tests. All of
> 	a sudden, I have to install Scalar::Util, where things were
> 	fine before Git.pm.

I recall Pasky talking about Scalar::Util removal and I thought
I took a patch.

 ... goes "git grep" ...

Ah the private edition of Error.pm pulls that in.  Sheesh.

^ permalink raw reply

* Re: git on HP-UX
From: Junio C Hamano @ 2006-07-07  0:20 UTC (permalink / raw)
  To: Pavel Roskin; +Cc: git
In-Reply-To: <1152197629.7720.10.camel@dv>

Pavel Roskin <proski@gnu.org> writes:

>> I needed following changes in order to make git compile on HP-UX:
>> +ifeq ($(uname_S),HP-UX)
>> +	NO_IPV6 = YesPlease
>> +	NO_CURL = YesPlease
>
> Is there any fundamental problem with curl and IPv6 on HP-UX?  I don't
> think so.
>
> Sorry for using your path as a bad example, but the appearance of such
> patches is a perfect argument for a real configure script.  If we
> continue patching Makefile, we'll drown in such conditionals.

Conditionals like 'ifdef NO_IPV6' in Makefile are good, but
conditionals switch on platforms to set/reset them are not.
A configure script to set them in config.mak.gen is the way to
go, I would agree.

> I hope the Autoconf based configure is on its way to git, but I don't
> see in in the "pu" branch yet.  I'm not very keen about reinventing
> Autoconf and hacking a hand-made configure script.

OK, you half-convinced me.  The other half came from a recent
series of patches to try using 'which' to detect executables,
which is another common mistake handcrafted configure script
makes, which autoconf people have solved for us long time ago.

^ permalink raw reply

* Re: [RFC/PATCH] git-svn: migrate out of contrib
From: Junio C Hamano @ 2006-07-07  0:20 UTC (permalink / raw)
  To: Eric Wong; +Cc: git
In-Reply-To: <11521700563472-git-send-email-normalperson@yhbt.net>

Overall it looks good.

9104 and 9105 fail when GIT_SVN_NO_LIB is unset and the
libsvn-*-perl is not available.  Maybe check this just like you
check and omit tests when svn or svnadmin is unavailable?

^ permalink raw reply

* [PATCH] Add "raw" output option to blobs in "tree" view format
From: Luben Tuikov @ 2006-07-07  6:39 UTC (permalink / raw)
  To: git

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

Add a "raw" output option to blobs in "tree" view format, so that the
user doesn't have to click on "blob", wait for the (binary) file to be
uploaded and shown in "blob" mode, and then click on "plain" to
download the (binary) file.

This is useful when the file is clearly binary and we don't want the
browser to upload and display it in "blob" mode, but we just want to
download it.  Case in point: pdf files, wlg.

Note: the "raw" format is equivalent to the blob->plain view, not
blob->head view. I.e. the view has the hash of the file as listed
by git-ls-tree, not just "HEAD".

Signed-off-by: Luben Tuikov <ltuikov@yahoo.com>
---
 gitweb/gitweb.cgi |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi
index 3e2790c..cce0753 100755
--- a/gitweb/gitweb.cgi
+++ b/gitweb/gitweb.cgi
@@ -1668,6 +1668,7 @@ sub git_tree {
 			      $cgi->a({-href => "$my_uri?" .
esc_param("p=$project;a=blob;h=$t_hash$base_key;f=$base$t_name")}, "blob") .
 #			      " | " . $cgi->a({-href => "$my_uri?" .
esc_param("p=$project;a=blame;h=$t_hash$base_key;f=$base$t_name")}, "blame") .
 			      " | " . $cgi->a({-href => "$my_uri?" .
esc_param("p=$project;a=history;h=$hash_base;f=$base$t_name")}, "history") .
+			      " | " . $cgi->a({-href => "$my_uri?" .
esc_param("p=$project;a=blob_plain;h=$t_hash;f=$base$t_name")}, "raw") .
 			      "</td>\n";
 		} elsif ($t_type eq "tree") {
 			print "<td class=\"list\">" .
-- 
1.4.1.g88ada

[-- Attachment #2: 2829251161-patch.patch --]
[-- Type: application/octet-stream, Size: 790 bytes --]

26f034dc7bf30e675d53da4f215ca2e1e6b88d1f
diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi
index 3e2790c..cce0753 100755
--- a/gitweb/gitweb.cgi
+++ b/gitweb/gitweb.cgi
@@ -1668,6 +1668,7 @@ sub git_tree {
 			      $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$t_hash$base_key;f=$base$t_name")}, "blob") .
 #			      " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blame;h=$t_hash$base_key;f=$base$t_name")}, "blame") .
 			      " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=history;h=$hash_base;f=$base$t_name")}, "history") .
+			      " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob_plain;h=$t_hash;f=$base$t_name")}, "raw") .
 			      "</td>\n";
 		} elsif ($t_type eq "tree") {
 			print "<td class=\"list\">" .

^ permalink raw reply related

* Re: [PATCH] Add "raw" output option to blobs in "tree" view format
From: Junio C Hamano @ 2006-07-07  6:58 UTC (permalink / raw)
  To: ltuikov; +Cc: git
In-Reply-To: <20060707063930.7752.qmail@web31805.mail.mud.yahoo.com>

Luben Tuikov <ltuikov@yahoo.com> writes:

> Add a "raw" output option to blobs in "tree" view format, so that the
> user doesn't have to click on "blob", wait for the (binary) file to be
> uploaded and shown in "blob" mode, and then click on "plain" to
> download the (binary) file.

I appreciate what you are trying to achieve, but at the same
time wonder if it would make more sense to simply teach a=blob
action to do this automatically, perhaps using /etc/mime.types
and/or File::MMagic.

If you know your MUA will mangle whitespace to make your patch
inapplicable, please do not add a patch to the message _and_
attach the patch to the message.  The mail-acceptance tools know
how to flatten MIME attachments, but if you have your log,
three-dash and then corrupt patch in the cover-letter part, and
then the true patch in the attachment part, the flattened result
will have the corrupt patch first to cause the patch application
to fail.  So please either (preferably) use a MUA that does not
corrupt your patches, or do a log in the message part with patch
only as attachment.

^ permalink raw reply

* Re: A note on merging conflicts..
From: Junio C Hamano @ 2006-07-07  8:26 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0606301927260.12404@g5.osdl.org>

Linus Torvalds <torvalds@osdl.org> writes:

> One thing that is _very_ useful to do is to do when you have a conflict is 
> this:
>
> 	git log -p HEAD MERGE_BASE..MERGE_HEAD -- conflicting-filename
>
> so that I wouldn't have to type that by hand ever again, and doing a
>
> 	git log -p --merge drivers/
>
> would automatically give me exactly that for all the unmerged files in 
> drivers/.
>
> Anybody want to try to make me happy, and learn some git internals at the 
> same time?

I was hoping somebody else would come forward, but it's been a
week, so here it is.

-- >8 --
[PATCH] git log -p --merge [[--] paths...]

This adds Linus's wish, "--merge" flag, which makes the above
expand to a rough equivalent to:

	git log -p HEAD MERGE_HEAD ^$(git-merge-base HEAD MERGE_HEAD) \
		-- $(git-ls-files -u [paths...] | cut -f2 | uniq)

Signed-off-by: Junio C Hamano <junkio@cox.net>
---
 revision.c |   53 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/revision.c b/revision.c
index 27fc1e3..e7128f2 100644
--- a/revision.c
+++ b/revision.c
@@ -548,6 +548,49 @@ static void add_pending_commit_list(stru
 	}
 }
 
+static void prepare_show_merge(struct rev_info *revs)
+{
+	struct commit_list *bases;
+	struct commit *head, *other;
+	unsigned char sha1[20];
+	const char **prune = NULL;
+	int i, prune_num = 1; /* counting terminating NULL */
+
+	if (get_sha1("HEAD", sha1) || !(head = lookup_commit(sha1)))
+		die("--merge without HEAD?");
+	if (get_sha1("MERGE_HEAD", sha1) || !(other = lookup_commit(sha1)))
+		die("--merge without MERGE_HEAD?");
+	add_pending_object(revs, &head->object, "HEAD");
+	add_pending_object(revs, &other->object, "MERGE_HEAD");
+	bases = get_merge_bases(head, other, 1);
+	while (bases) {
+		struct commit *it = bases->item;
+		struct commit_list *n = bases->next;
+		free(bases);
+		bases = n;
+		it->object.flags |= UNINTERESTING;
+		add_pending_object(revs, &it->object, "(merge-base)");
+	}
+
+	if (!active_nr)
+		read_cache();
+	for (i = 0; i < active_nr; i++) {
+		struct cache_entry *ce = active_cache[i];
+		if (!ce_stage(ce))
+			continue;
+		if (ce_path_match(ce, revs->prune_data)) {
+			prune_num++;
+			prune = xrealloc(prune, sizeof(*prune) * prune_num);
+			prune[prune_num-2] = ce->name;
+			prune[prune_num-1] = NULL;
+		}
+		while ((i+1 < active_nr) &&
+		       ce_same_name(ce, active_cache[i+1]))
+			i++;
+	}
+	revs->prune_data = prune;
+}
+
 /*
  * Parse revision information, filling in the "rev_info" structure,
  * and removing the used arguments from the argument list.
@@ -557,7 +600,7 @@ static void add_pending_commit_list(stru
  */
 int setup_revisions(int argc, const char **argv, struct rev_info *revs, const char *def)
 {
-	int i, flags, seen_dashdash;
+	int i, flags, seen_dashdash, show_merge;
 	const char **unrecognized = argv + 1;
 	int left = 1;
 
@@ -574,7 +617,7 @@ int setup_revisions(int argc, const char
 		break;
 	}
 
-	flags = 0;
+	flags = show_merge = 0;
 	for (i = 1; i < argc; i++) {
 		struct object *object;
 		const char *arg = argv[i];
@@ -641,6 +684,10 @@ int setup_revisions(int argc, const char
 				def = argv[i];
 				continue;
 			}
+			if (!strcmp(arg, "--merge")) {
+				show_merge = 1;
+				continue;
+			}
 			if (!strcmp(arg, "--topo-order")) {
 				revs->topo_order = 1;
 				continue;
@@ -861,6 +908,8 @@ int setup_revisions(int argc, const char
 		object = get_reference(revs, arg, sha1, flags ^ local_flags);
 		add_pending_object(revs, object, arg);
 	}
+	if (show_merge)
+		prepare_show_merge(revs);
 	if (def && !revs->pending.nr) {
 		unsigned char sha1[20];
 		struct object *object;
-- 
1.4.1.g4d2af

^ permalink raw reply related

* [PATCH] git-svn: migrate out of contrib
From: Eric Wong @ 2006-07-07 10:03 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7v8xn64658.fsf@assigned-by-dhcp.cox.net>

Allow NO_SVN_TESTS to be defined to skip git-svn tests.  These
tests are time-consuming due to SVN being slow, and even more so
if SVN Perl libraries are not available.

Also added a check for SVN::Core so test 910[45] don't fail
if the user doesn't have those installed, thanks to Junio for
noticing this.

Signed-off-by: Eric Wong <normalperson@yhbt.net>
---
 Junio C Hamano <junkio@cox.net> wrote:
 > Overall it looks good.
 > 
 > 9104 and 9105 fail when GIT_SVN_NO_LIB is unset and the
 > libsvn-*-perl is not available.  Maybe check this just like you
 > check and omit tests when svn or svnadmin is unavailable?

 Done.  While I was at it, I changed the test != to test -eq
 and brought the similarity below the threshold, which may
 make me want to expand on another patch...

 .gitignore                                         |    1 
 {contrib/git-svn => Documentation}/git-svn.txt     |    0 
 Makefile                                           |    6 ++-
 contrib/git-svn/.gitignore                         |    4 --
 contrib/git-svn/Makefile                           |   44 --------------------
 contrib/git-svn/git-svn.perl => git-svn.perl       |    2 -
 t/Makefile                                         |   10 +++++
 {contrib/git-svn/t => t}/lib-git-svn.sh            |   29 ++++++++-----
 .../t9100-git-svn-basic.sh                         |    4 ++
 .../t9101-git-svn-props.sh                         |    0 
 .../t9102-git-svn-deep-rmdir.sh                    |    0 
 .../t9103-git-svn-graft-branches.sh                |    0 
 .../t9104-git-svn-follow-parent.sh                 |    0 
 .../t9105-git-svn-commit-diff.sh                   |    0 
 14 files changed, 37 insertions(+), 63 deletions(-)

diff --git a/.gitignore b/.gitignore
index 2bcc604..52d61f3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -107,6 +107,7 @@ git-ssh-push
 git-ssh-upload
 git-status
 git-stripspace
+git-svn
 git-svnimport
 git-symbolic-ref
 git-tag
diff --git a/contrib/git-svn/git-svn.txt b/Documentation/git-svn.txt
similarity index 100%
rename from contrib/git-svn/git-svn.txt
rename to Documentation/git-svn.txt
diff --git a/Makefile b/Makefile
index 202f261..a0e90c0 100644
--- a/Makefile
+++ b/Makefile
@@ -33,6 +33,10 @@ #
 # Define NO_SYMLINK_HEAD if you never want .git/HEAD to be a symbolic link.
 # Enable it on Windows.  By default, symrefs are still used.
 #
+# Define NO_SVN_TESTS if you want to skip time-consuming SVN interopability
+# tests.  These tests take up a significant amount of the total test time
+# but are not needed unless you plan to talk to SVN repos.
+#
 # Define PPC_SHA1 environment variable when running make to make use of
 # a bundled SHA1 routine optimized for PowerPC.
 #
@@ -134,7 +138,7 @@ SCRIPT_PERL = \
 	git-shortlog.perl git-rerere.perl \
 	git-annotate.perl git-cvsserver.perl \
 	git-svnimport.perl git-mv.perl git-cvsexportcommit.perl \
-	git-send-email.perl
+	git-send-email.perl git-svn.perl
 
 SCRIPT_PYTHON = \
 	git-merge-recursive.py
diff --git a/contrib/git-svn/.gitignore b/contrib/git-svn/.gitignore
deleted file mode 100644
index d8d87e3..0000000
--- a/contrib/git-svn/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-git-svn
-git-svn.xml
-git-svn.html
-git-svn.1
diff --git a/contrib/git-svn/Makefile b/contrib/git-svn/Makefile
deleted file mode 100644
index 7c20946..0000000
--- a/contrib/git-svn/Makefile
+++ /dev/null
@@ -1,44 +0,0 @@
-all: git-svn
-
-prefix?=$(HOME)
-bindir=$(prefix)/bin
-mandir=$(prefix)/man
-man1=$(mandir)/man1
-INSTALL?=install
-doc_conf=../../Documentation/asciidoc.conf
--include ../../config.mak
-
-git-svn: git-svn.perl
-	cp $< $@
-	chmod +x $@
-
-install: all
-	$(INSTALL) -d -m755 $(DESTDIR)$(bindir)
-	$(INSTALL) git-svn $(DESTDIR)$(bindir)
-
-install-doc: doc
-	$(INSTALL) git-svn.1 $(DESTDIR)$(man1)
-
-doc: git-svn.1
-git-svn.1 : git-svn.xml
-	xmlto man git-svn.xml
-git-svn.xml : git-svn.txt
-	asciidoc -b docbook -d manpage \
-		-f ../../Documentation/asciidoc.conf $<
-git-svn.html : git-svn.txt
-	asciidoc -b xhtml11 -d manpage \
-		-f ../../Documentation/asciidoc.conf $<
-test: git-svn
-	cd t && for i in t????-*.sh; do $(SHELL) ./$$i $(TEST_FLAGS); done
-
-# we can test NO_OPTIMIZE_COMMITS independently of LC_ALL
-full-test:
-	$(MAKE) test GIT_SVN_NO_LIB=1 GIT_SVN_NO_OPTIMIZE_COMMITS=1 LC_ALL=C
-	$(MAKE) test GIT_SVN_NO_LIB=0 GIT_SVN_NO_OPTIMIZE_COMMITS=1 LC_ALL=C
-	$(MAKE) test GIT_SVN_NO_LIB=1 GIT_SVN_NO_OPTIMIZE_COMMITS=0 \
-							LC_ALL=en_US.UTF-8
-	$(MAKE) test GIT_SVN_NO_LIB=0 GIT_SVN_NO_OPTIMIZE_COMMITS=0 \
-							LC_ALL=en_US.UTF-8
-
-clean:
-	rm -f git-svn *.xml *.html *.1
diff --git a/contrib/git-svn/git-svn.perl b/git-svn.perl
similarity index 100%
rename from contrib/git-svn/git-svn.perl
rename to git-svn.perl
index 8bc4188..145eaa8 100755
--- a/contrib/git-svn/git-svn.perl
+++ b/git-svn.perl
@@ -8,7 +8,7 @@ use vars qw/	$AUTHOR $VERSION
 		$GIT_SVN_INDEX $GIT_SVN
 		$GIT_DIR $GIT_SVN_DIR $REVDB/;
 $AUTHOR = 'Eric Wong <normalperson@yhbt.net>';
-$VERSION = '1.1.1-broken';
+$VERSION = '@@GIT_VERSION@@';
 
 use Cwd qw/abs_path/;
 $GIT_DIR = abs_path($ENV{GIT_DIR} || '.git');
diff --git a/t/Makefile b/t/Makefile
index 632c55f..8983509 100644
--- a/t/Makefile
+++ b/t/Makefile
@@ -11,6 +11,7 @@ # Shell quote;
 SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
 
 T = $(wildcard t[0-9][0-9][0-9][0-9]-*.sh)
+TSVN = $(wildcard t91[0-9][0-9]-*.sh)
 
 ifdef NO_PYTHON
 	GIT_TEST_OPTS += --no-python
@@ -24,6 +25,15 @@ all: $(T) clean
 clean:
 	rm -fr trash
 
+# we can test NO_OPTIMIZE_COMMITS independently of LC_ALL
+full-svn-test:
+	$(MAKE) $(TSVN) GIT_SVN_NO_LIB=1 GIT_SVN_NO_OPTIMIZE_COMMITS=1 LC_ALL=C
+	$(MAKE) $(TSVN) GIT_SVN_NO_LIB=0 GIT_SVN_NO_OPTIMIZE_COMMITS=1 LC_ALL=C
+	$(MAKE) $(TSVN) GIT_SVN_NO_LIB=1 GIT_SVN_NO_OPTIMIZE_COMMITS=0 \
+							LC_ALL=en_US.UTF-8
+	$(MAKE) $(TSVN) GIT_SVN_NO_LIB=0 GIT_SVN_NO_OPTIMIZE_COMMITS=0 \
+							LC_ALL=en_US.UTF-8
+
 .PHONY: $(T) clean
 .NOTPARALLEL:
 
diff --git a/contrib/git-svn/t/lib-git-svn.sh b/t/lib-git-svn.sh
similarity index 49%
rename from contrib/git-svn/t/lib-git-svn.sh
rename to t/lib-git-svn.sh
index d7f972a..29a1e72 100644
--- a/contrib/git-svn/t/lib-git-svn.sh
+++ b/t/lib-git-svn.sh
@@ -1,30 +1,35 @@
-PATH=$PWD/../:$PATH
-if test -d ../../../t
+. ./test-lib.sh
+
+if test -n "$NO_SVN_TESTS"
 then
-    cd ../../../t
-else
-    echo "Must be run in contrib/git-svn/t" >&2
-    exit 1
+	test_expect_success 'skipping git-svn tests, NO_SVN_TESTS defined' :
+	test_done
+	exit
 fi
 
-. ./test-lib.sh
-
 GIT_DIR=$PWD/.git
 GIT_SVN_DIR=$GIT_DIR/svn/git-svn
 SVN_TREE=$GIT_SVN_DIR/svn-tree
 
+perl -e 'use SVN::Core' >/dev/null 2>&1
+if test $? -ne 0
+then
+   echo 'Perl SVN libraries not found, tests requiring those will be skipped'
+   GIT_SVN_NO_LIB=1
+fi
+
 svnadmin >/dev/null 2>&1
-if test $? != 1
+if test $? -ne 1
 then
-    test_expect_success 'skipping contrib/git-svn test' :
+    test_expect_success 'skipping git-svn tests, svnadmin not found' :
     test_done
     exit
 fi
 
 svn >/dev/null 2>&1
-if test $? != 1
+if test $? -ne 1
 then
-    test_expect_success 'skipping contrib/git-svn test' :
+    test_expect_success 'skipping git-svn tests, svn not found' :
     test_done
     exit
 fi
diff --git a/contrib/git-svn/t/t0000-contrib-git-svn.sh b/t/t9100-git-svn-basic.sh
old mode 100644
new mode 100755
similarity index 98%
rename from contrib/git-svn/t/t0000-contrib-git-svn.sh
rename to t/t9100-git-svn-basic.sh
index b482bb6..bf1d638
--- a/contrib/git-svn/t/t0000-contrib-git-svn.sh
+++ b/t/t9100-git-svn-basic.sh
@@ -3,7 +3,7 @@ #
 # Copyright (c) 2006 Eric Wong
 #
 
-test_description='git-svn tests'
+test_description='git-svn basic tests'
 GIT_SVN_LC_ALL=$LC_ALL
 
 case "$LC_ALL" in
@@ -17,6 +17,8 @@ esac
 
 . ./lib-git-svn.sh
 
+echo 'define NO_SVN_TESTS to skip git-svn tests'
+
 mkdir import
 cd import
 
diff --git a/contrib/git-svn/t/t0001-contrib-git-svn-props.sh b/t/t9101-git-svn-props.sh
old mode 100644
new mode 100755
similarity index 100%
rename from contrib/git-svn/t/t0001-contrib-git-svn-props.sh
rename to t/t9101-git-svn-props.sh
diff --git a/contrib/git-svn/t/t0002-deep-rmdir.sh b/t/t9102-git-svn-deep-rmdir.sh
old mode 100644
new mode 100755
similarity index 100%
rename from contrib/git-svn/t/t0002-deep-rmdir.sh
rename to t/t9102-git-svn-deep-rmdir.sh
diff --git a/contrib/git-svn/t/t0003-graft-branches.sh b/t/t9103-git-svn-graft-branches.sh
old mode 100644
new mode 100755
similarity index 100%
rename from contrib/git-svn/t/t0003-graft-branches.sh
rename to t/t9103-git-svn-graft-branches.sh
diff --git a/contrib/git-svn/t/t0004-follow-parent.sh b/t/t9104-git-svn-follow-parent.sh
old mode 100644
new mode 100755
similarity index 100%
rename from contrib/git-svn/t/t0004-follow-parent.sh
rename to t/t9104-git-svn-follow-parent.sh
diff --git a/contrib/git-svn/t/t0005-commit-diff.sh b/t/t9105-git-svn-commit-diff.sh
old mode 100644
new mode 100755
similarity index 100%
rename from contrib/git-svn/t/t0005-commit-diff.sh
rename to t/t9105-git-svn-commit-diff.sh
-- 
1.4.1.g3dc65

^ permalink raw reply related

* [PATCH] diff.c: respect diff.renames config option
From: Eric Wong @ 2006-07-07 10:10 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Eric Wong
In-Reply-To: <11522670452824-git-send-email-normalperson@yhbt.net>

diff.renames is mentioned several times in the documentation,
but to my surprise it didn't do anything before this patch.

Signed-off-by: Eric Wong <normalperson@yhbt.net>
---
 Documentation/config.txt |    5 +++++
 diff.c                   |   12 ++++++++++++
 2 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index f075f19..5290a8f 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -114,6 +114,11 @@ diff.renameLimit::
 	The number of files to consider when performing the copy/rename
 	detection; equivalent to the git diff option '-l'.
 
+diff.renames::
+	Tells git to detect renames.  If set to any boolean value, it
+	will enable basic rename detection.  If set to "copies" or
+	"copy", it will detect copies, as well.
+
 format.headers::
 	Additional email headers to include in a patch to be submitted
 	by mail.  See gitlink:git-format-patch[1].
diff --git a/diff.c b/diff.c
index 507e401..223622a 100644
--- a/diff.c
+++ b/diff.c
@@ -13,6 +13,7 @@ #include "xdiff-interface.h"
 
 static int use_size_cache;
 
+static int diff_detect_rename_default = 0;
 static int diff_rename_limit_default = -1;
 static int diff_use_color_default = 0;
 
@@ -120,6 +121,16 @@ int git_diff_config(const char *var, con
 			diff_use_color_default = git_config_bool(var, value);
 		return 0;
 	}
+	if (!strcmp(var, "diff.renames")) {
+		if (!value)
+			diff_detect_rename_default = DIFF_DETECT_RENAME;
+		else if (!strcasecmp(value, "copies") ||
+			 !strcasecmp(value, "copy"))
+			diff_detect_rename_default = DIFF_DETECT_COPY;
+		else
+			diff_detect_rename_default = git_config_bool(var,value);
+		return 0;
+	}
 	if (!strncmp(var, "diff.color.", 11)) {
 		int slot = parse_diff_color_slot(var, 11);
 		diff_colors[slot] = parse_diff_color_value(value, var);
@@ -1429,6 +1440,7 @@ void diff_setup(struct diff_options *opt
 	options->change = diff_change;
 	options->add_remove = diff_addremove;
 	options->color_diff = diff_use_color_default;
+	options->detect_rename = diff_detect_rename_default;
 }
 
 int diff_setup_done(struct diff_options *options)
-- 
1.4.1.g3dc65

^ permalink raw reply related

* [PATCH 0/1] I forgot to run format-patch with the -M flag
From: Eric Wong @ 2006-07-07 10:10 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Eric Wong

Now I can forget more often :)  Unless the similarity is too low.

I'm not too sure if I'd want to set similarity or find-copies-harder
into my config just yet, since they depend on the situation.  But I
usually want renames in my diffs.

-- 
Eric Wong

^ permalink raw reply

* [PATCH] builtin-log: respect diff configuration options
From: Eric Wong @ 2006-07-07 10:10 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Eric Wong
In-Reply-To: <11522670473116-git-send-email-normalperson@yhbt.net>

The log commands are all capable of generating diffs, so we
should respect those configuration options for diffs here.

Signed-off-by: Eric Wong <normalperson@yhbt.net>
---
 builtin-log.c |    7 +++++--
 1 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/builtin-log.c b/builtin-log.c
index 864c6cd..698b71e 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -47,6 +47,7 @@ int cmd_whatchanged(int argc, const char
 {
 	struct rev_info rev;
 
+	git_config(git_diff_config);
 	init_revisions(&rev);
 	rev.diff = 1;
 	rev.diffopt.recursive = 1;
@@ -61,6 +62,7 @@ int cmd_show(int argc, const char **argv
 {
 	struct rev_info rev;
 
+	git_config(git_diff_config);
 	init_revisions(&rev);
 	rev.diff = 1;
 	rev.diffopt.recursive = 1;
@@ -77,6 +79,7 @@ int cmd_log(int argc, const char **argv,
 {
 	struct rev_info rev;
 
+	git_config(git_diff_config);
 	init_revisions(&rev);
 	rev.always_show_header = 1;
 	cmd_log_init(argc, argv, envp, &rev);
@@ -102,7 +105,7 @@ static int git_format_config(const char 
 		strcat(extra_headers, value);
 		return 0;
 	}
-	return git_default_config(var, value);
+	return git_diff_config(var, value);
 }
 
 
@@ -234,6 +237,7 @@ int cmd_format_patch(int argc, const cha
 	struct diff_options patch_id_opts;
 	char *add_signoff = NULL;
 
+	git_config(git_format_config);
 	init_revisions(&rev);
 	rev.commit_format = CMIT_FMT_EMAIL;
 	rev.verbose_header = 1;
@@ -243,7 +247,6 @@ int cmd_format_patch(int argc, const cha
 	rev.diffopt.msg_sep = "";
 	rev.diffopt.recursive = 1;
 
-	git_config(git_format_config);
 	rev.extra_headers = extra_headers;
 
 	/*
-- 
1.4.1.g3dc65

^ 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