Git development
 help / color / mirror / Atom feed
* cvs2svn/cvs2git version 2.2.0 has been released
From: Michael Haggerty @ 2008-11-23  9:00 UTC (permalink / raw)
  To: announce, Git Mailing List, mercurial, Bazaar

cvs2svn/cvs2git 2.2.0 has been released.

cvs2svn/cvs2git [1] is a free program that converts CVS repositories to
Subversion, git, Mercurial, or Bazaar, including all project history and
metadata.  cvs2svn can convert just about any CVS repository we've ever
seen, including gcc, Mozilla, FreeBSD, KDE, and GNOME.  Conversion to
the DVCSs is via dumping output in git-fast-import format.

cvs2svn infers what happened in the history of your CVS repository and
replicates that history as accurately as possible in the target SCM.
All revisions, branches, tags, log messages, author names, and commit
dates are converted.  cvs2svn deduces what CVS modifications were made
at the same time, and outputs these modifications grouped together as
changesets in the target SCM.  cvs2svn also deals with many CVS quirks
and is highly configurable.  See the comprehensive feature list [2].


Significant changes in release 2.2.0:

* By default, omit trivial CVS import branches from conversion.

* Allow vendor branches to be excluded (grafting child symbols to
  trunk).

* By default, don't include .cvsignore files in output (except as
  svn:ignore).

* Allow arbitrary SVN directories to be created when a project is
  created.

* cvs2git:
  - Omit the tag fixup branch if a tag can be copied from an existing
    revision.
  - Generate lightweight rather than annotated tags.

* Converting to Mercurial:
  - Add an option to set the maximum number of merge sources per commit.
    (Mercurial only allows a commit to have 0, 1, or 2 ancestors.)
  - Allow file contents to be written inline in git-fast-import streams
    (hg fast-import doesn't support predefined blobs).

* Allow the user to specify templates for cvs2svn-generated log
  messages.

* Fixed a few minor bugs.


For more information, see the latest CHANGES file [3].

You can download the new release here [4].  (Its MD5 checksum is
466b757fdef5378a46bba4ceefd047a4.)

Please send any bug reports and comments to users@cvs2svn.tigris.org.

Michael Haggerty, on behalf of the cvs2svn development team.

[1] http://cvs2svn.tigris.org
[2] http://cvs2svn.tigris.org/features.html
[3]
http://cvs2svn.tigris.org/source/browse/cvs2svn/tags/2.2.0/CHANGES?view=markup
[4]
http://cvs2svn.tigris.org/files/documents/1462/44372/cvs2svn-2.2.0.tar.gz

^ permalink raw reply

* [PATCH 1/2] Simplify and fix t9301
From: Johannes Schindelin @ 2008-11-23 11:55 UTC (permalink / raw)
  To: Miklos Vajna; +Cc: git, gitster
In-Reply-To: <1227378168-14992-1-git-send-email-vmiklos@frugalware.org>


The recent addition to the test to show the tag related breakage was
not minimal.

Further, it tested for the string "tag" at the start of the lines,
which matches, "tagger", too.  Test for "tag " instead.

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

	I'll have no problem if this is squashed into Miklos' patch.

 t/t9301-fast-export.sh |    5 +----
 1 files changed, 1 insertions(+), 4 deletions(-)

diff --git a/t/t9301-fast-export.sh b/t/t9301-fast-export.sh
index 078832f..9af50b5 100755
--- a/t/t9301-fast-export.sh
+++ b/t/t9301-fast-export.sh
@@ -234,11 +234,8 @@ test_expect_success 'fast-export -C -C | fast-import' '
 test_expect_failure 'fast-export | fast-import when master is tagged' '
 
 	git tag -m msg last &&
-	rm -rf new &&
-	mkdir new &&
-	git --git-dir=new/.git init &&
 	git fast-export -C -C --signed-tags=strip --all > output &&
-	test $(grep -c "^tag" output) = 3
+	test $(grep -c "^tag " output) = 3
 
 '
 
-- 
1.6.0.2.749.g0cc32

^ permalink raw reply related

* [BUGFIX PATCH 2/2] fast-export: use an unsorted string list for extra_refs
From: Johannes Schindelin @ 2008-11-23 11:55 UTC (permalink / raw)
  To: Miklos Vajna; +Cc: git, gitster
In-Reply-To: <alpine.DEB.1.00.0811231254580.30769@pacific.mpi-cbg.de>


The list extra_refs contains tags and the objects referenced by them,
so that they can be handled at the end.  When a tag references a
commit, that commit is added to the list using the same name.

Also, the function handle_tags_and_duplicates() relies on the order
the items were added to extra_refs, so clearly we do not want to
use a sorted list here.

Noticed by Miklos Vajna.

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

	My bad.  Sorry.

 builtin-fast-export.c  |    4 ++--
 t/t9301-fast-export.sh |    2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/builtin-fast-export.c b/builtin-fast-export.c
index 7c93eb8..7d5d57a 100644
--- a/builtin-fast-export.c
+++ b/builtin-fast-export.c
@@ -354,7 +354,7 @@ static void get_tags_and_duplicates(struct object_array *pending,
 		case OBJ_TAG:
 			tag = (struct tag *)e->item;
 			while (tag && tag->object.type == OBJ_TAG) {
-				string_list_insert(full_name, extra_refs)->util = tag;
+				string_list_append(full_name, extra_refs)->util = tag;
 				tag = (struct tag *)tag->tagged;
 			}
 			if (!tag)
@@ -374,7 +374,7 @@ static void get_tags_and_duplicates(struct object_array *pending,
 		}
 		if (commit->util)
 			/* more than one name for the same object */
-			string_list_insert(full_name, extra_refs)->util = commit;
+			string_list_append(full_name, extra_refs)->util = commit;
 		else
 			commit->util = full_name;
 	}
diff --git a/t/t9301-fast-export.sh b/t/t9301-fast-export.sh
index 9af50b5..2057435 100755
--- a/t/t9301-fast-export.sh
+++ b/t/t9301-fast-export.sh
@@ -231,7 +231,7 @@ test_expect_success 'fast-export -C -C | fast-import' '
 
 '
 
-test_expect_failure 'fast-export | fast-import when master is tagged' '
+test_expect_success 'fast-export | fast-import when master is tagged' '
 
 	git tag -m msg last &&
 	git fast-export -C -C --signed-tags=strip --all > output &&
-- 
1.6.0.2.749.g0cc32

^ permalink raw reply related

* [PATCH] gitk: map / to focus the search box
From: Giuseppe Bilotta @ 2008-11-23 17:01 UTC (permalink / raw)
  To: git; +Cc: Paul Mackerras, Junio C Hamano, Giuseppe Bilotta

The / key is often used to initiate searches (less, vim, some web
browsers). We change the binding for the / (slash) key from 'find next'
to 'focus the search box' to follow this convention.
---
 gitk-git/gitk |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/gitk-git/gitk b/gitk-git/gitk
index 6b671a6..8b60632 100644
--- a/gitk-git/gitk
+++ b/gitk-git/gitk
@@ -2271,7 +2271,7 @@ proc makewindow {} {
     bindkey b prevfile
     bindkey d "$ctext yview scroll 18 units"
     bindkey u "$ctext yview scroll -18 units"
-    bindkey / {dofind 1 1}
+    bindkey / {focus $fstring}
     bindkey <Key-Return> {dofind 1 1}
     bindkey ? {dofind -1 1}
     bindkey f nextfile
-- 
1.5.6.5

^ permalink raw reply related

* Re: [BUGFIX PATCH 2/2] fast-export: use an unsorted string list for extra_refs
From: Miklos Vajna @ 2008-11-23 18:03 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: git, gitster
In-Reply-To: <alpine.DEB.1.00.0811231255380.30769@pacific.mpi-cbg.de>

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

On Sun, Nov 23, 2008 at 12:55:54PM +0100, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> 
> The list extra_refs contains tags and the objects referenced by them,
> so that they can be handled at the end.  When a tag references a
> commit, that commit is added to the list using the same name.
> 
> Also, the function handle_tags_and_duplicates() relies on the order
> the items were added to extra_refs, so clearly we do not want to
> use a sorted list here.

Tested-by: Miklos Vajna <vmiklos@frugalware.org>

Thanks!

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

^ permalink raw reply

* Re: git workshop in Sweden/Denmark
From: nadim khemir @ 2008-11-23 18:48 UTC (permalink / raw)
  To: git
In-Reply-To: <4925257F.9060900@op5.se>

On Thursday 20 November 2008 09.53.19 Andreas Ericsson wrote:
> > Lund.pm and Data-foreningen are trying to organize a 'git' workshop.
> > - Can you be :
> >         - a speaker
> >         - a sponsor
>
> I've been speaking enough on oss conferences this year and feel I don't
> have time to spend on making slides and preparing for another conference,
> but I'd love to attend and can almost certainly help out on the workshop
> if needed.

Helping at the workshop is even better than having a talk. This is supposed to 
be hands on to help people learn git and fix problems they have.

> > - If you come, what would you like to learn, discuss?
>
> I'm primarily interested in finding developers that want to integrate git
> with other applications, such as IDE's. I need to know what they would
> need from a git library so I can properly prioritize the different todos
> for libgit2.
As you may have seen in my other mail, I will be taking over the maintenance 
of Git.pm and related perl modules. Having a Perlm module based on the 
functionality of libgit is in my plans. I've tried to follow the discussion 
around libgit (specially the re-licensing discussion) and I will certainly 
try to be actively listening to what happends there.

As for the integration in IDEs. How's the integration in Eclipse? There are 
two perl projects that may give you input. Padre and Kephra.

Cheers, Nadim

^ permalink raw reply

* Re: Problem with Git.pm bidi_pipe methods
From: nadim khemir @ 2008-11-23 19:03 UTC (permalink / raw)
  To: git
In-Reply-To: <20081024001446.GE17717@plop>

On Friday 24 October 2008 02.14.46 Philippe Bruhat (BooK) wrote:
> To be able to call commit-tree from a Perl program, I had to use
> command_bidi_pipe() to pass the message on standard input, and get the
> ...

Hi Philippe, I'm going to take over the Git.pm maintenance and I'd be happy to 
discuss this problem with you (you know whwere to find me right ;) and I'll 
be happy to hear your suggestions too.

Nadim.

^ permalink raw reply

* [PATCH] git-gui: french translation update
From: Christian Couder @ 2008-11-23 19:52 UTC (permalink / raw)
  To: Shawn O. Pearce; +Cc: git


Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
 git-gui/po/fr.po | 1124 +++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 827 insertions(+), 297 deletions(-)

	As usual, I hope there will be no encoding problems.

diff --git a/git-gui/po/fr.po b/git-gui/po/fr.po
index 26b866f..45773ab 100644
--- a/git-gui/po/fr.po
+++ b/git-gui/po/fr.po
@@ -1,4 +1,4 @@
-# translation of fr.po to Français
+# translation of fr.po to French
 # Translation of git-gui to French.
 # Copyright (C) 2008 Shawn Pearce, et al.
 # This file is distributed under the same license as the git package.
@@ -9,43 +9,43 @@ msgid ""
 msgstr ""
 "Project-Id-Version: fr\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-08-02 14:45-0700\n"
-"PO-Revision-Date: 2008-08-11 17:12-0400\n"
-"Last-Translator: Alexandre Bourget <alexandre.bourget@savoirfairelinux.com>\n"
-"Language-Team: Français <fr@li.org>\n"
+"POT-Creation-Date: 2008-11-16 13:56-0800\n"
+"PO-Revision-Date: 2008-11-20 10:20+0100\n"
+"Last-Translator: Christian Couder <chriscool@tuxfamily.org>\n"
+"Language-Team: French\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "X-Generator: KBabel 1.11.4\n"
 "Plural-Forms:  nplurals=2; plural=(n > 1);\n"
 
-#: git-gui.sh:41 git-gui.sh:688 git-gui.sh:702 git-gui.sh:715 git-gui.sh:798
-#: git-gui.sh:817
+#: git-gui.sh:41 git-gui.sh:737 git-gui.sh:751 git-gui.sh:764 git-gui.sh:847
+#: git-gui.sh:866
 msgid "git-gui: fatal error"
 msgstr "git-gui: erreur fatale"
 
-#: git-gui.sh:644
+#: git-gui.sh:689
 #, tcl-format
 msgid "Invalid font specified in %s:"
 msgstr "Police invalide spécifiée dans %s :"
 
-#: git-gui.sh:674
+#: git-gui.sh:723
 msgid "Main Font"
 msgstr "Police principale"
 
-#: git-gui.sh:675
+#: git-gui.sh:724
 msgid "Diff/Console Font"
 msgstr "Police diff/console"
 
-#: git-gui.sh:689
+#: git-gui.sh:738
 msgid "Cannot find git in PATH."
 msgstr "Impossible de trouver git dans PATH."
 
-#: git-gui.sh:716
+#: git-gui.sh:765
 msgid "Cannot parse Git version string:"
 msgstr "Impossible de parser la version de Git :"
 
-#: git-gui.sh:734
+#: git-gui.sh:783
 #, tcl-format
 msgid ""
 "Git version cannot be determined.\n"
@@ -64,381 +64,446 @@ msgstr ""
 "\n"
 "Peut'on considérer que '%s' est en version 1.5.0 ?\n"
 
-#: git-gui.sh:972
+#: git-gui.sh:1062
 msgid "Git directory not found:"
 msgstr "Impossible de trouver le répertoire git :"
 
-#: git-gui.sh:979
+#: git-gui.sh:1069
 msgid "Cannot move to top of working directory:"
 msgstr "Impossible d'aller à la racine du répertoire de travail :"
 
-#: git-gui.sh:986
+#: git-gui.sh:1076
 msgid "Cannot use funny .git directory:"
 msgstr "Impossible d'utiliser le répertoire .git:"
 
-#: git-gui.sh:991
+#: git-gui.sh:1081
 msgid "No working directory"
 msgstr "Aucun répertoire de travail"
 
-#: git-gui.sh:1138 lib/checkout_op.tcl:305
+#: git-gui.sh:1247 lib/checkout_op.tcl:305
 msgid "Refreshing file status..."
 msgstr "Rafraichissement du status des fichiers..."
 
-#: git-gui.sh:1194
+#: git-gui.sh:1303
 msgid "Scanning for modified files ..."
 msgstr "Recherche de fichiers modifiés..."
 
-#: git-gui.sh:1369 lib/browser.tcl:246
+#: git-gui.sh:1367
+msgid "Calling prepare-commit-msg hook..."
+msgstr "Lancement de l'action de préparation du message de commit..."
+
+#: git-gui.sh:1384
+msgid "Commit declined by prepare-commit-msg hook."
+msgstr "Commit refusé par l'action de préparation du message de commit."
+
+#: git-gui.sh:1542 lib/browser.tcl:246
 msgid "Ready."
 msgstr "Prêt."
 
-#: git-gui.sh:1635
+#: git-gui.sh:1819
 msgid "Unmodified"
 msgstr "Non modifié"
 
-#: git-gui.sh:1637
+#: git-gui.sh:1821
 msgid "Modified, not staged"
 msgstr "Modifié, pas indexé"
 
-#: git-gui.sh:1638 git-gui.sh:1643
+#: git-gui.sh:1822 git-gui.sh:1830
 msgid "Staged for commit"
 msgstr "Indexé"
 
-#: git-gui.sh:1639 git-gui.sh:1644
+#: git-gui.sh:1823 git-gui.sh:1831
 msgid "Portions staged for commit"
 msgstr "Portions indexées"
 
-#: git-gui.sh:1640 git-gui.sh:1645
+#: git-gui.sh:1824 git-gui.sh:1832
 msgid "Staged for commit, missing"
 msgstr "Indexés, manquant"
 
-#: git-gui.sh:1642
+#: git-gui.sh:1826
+msgid "File type changed, not staged"
+msgstr "Le type de fichier a changé, non indexé"
+
+#: git-gui.sh:1827
+msgid "File type changed, staged"
+msgstr "Le type de fichier a changé, indexé"
+
+#: git-gui.sh:1829
 msgid "Untracked, not staged"
 msgstr "Non versionné, non indexé"
 
-#: git-gui.sh:1647
+#: git-gui.sh:1834
 msgid "Missing"
 msgstr "Manquant"
 
-#: git-gui.sh:1648
+#: git-gui.sh:1835
 msgid "Staged for removal"
 msgstr "Indexé pour suppression"
 
-#: git-gui.sh:1649
+#: git-gui.sh:1836
 msgid "Staged for removal, still present"
 msgstr "Indexé pour suppression, toujours présent"
 
-#: git-gui.sh:1651 git-gui.sh:1652 git-gui.sh:1653 git-gui.sh:1654
+#: git-gui.sh:1838 git-gui.sh:1839 git-gui.sh:1840 git-gui.sh:1841
+#: git-gui.sh:1842 git-gui.sh:1843
 msgid "Requires merge resolution"
 msgstr "Nécessite la résolution d'une fusion"
 
-#: git-gui.sh:1689
+#: git-gui.sh:1878
 msgid "Starting gitk... please wait..."
 msgstr "Lancement de gitk... un instant..."
 
-#: git-gui.sh:1698
+#: git-gui.sh:1887
 msgid "Couldn't find gitk in PATH"
 msgstr "Impossible de trouver gitk dans PATH."
 
-#: git-gui.sh:1948 lib/choose_repository.tcl:36
+#: git-gui.sh:2280 lib/choose_repository.tcl:36
 msgid "Repository"
 msgstr "Dépôt"
 
-#: git-gui.sh:1949
+#: git-gui.sh:2281
 msgid "Edit"
 msgstr "Edition"
 
-#: git-gui.sh:1951 lib/choose_rev.tcl:561
+#: git-gui.sh:2283 lib/choose_rev.tcl:561
 msgid "Branch"
 msgstr "Branche"
 
-#: git-gui.sh:1954 lib/choose_rev.tcl:548
+#: git-gui.sh:2286 lib/choose_rev.tcl:548
 msgid "Commit@@noun"
 msgstr "Commit"
 
-#: git-gui.sh:1957 lib/merge.tcl:120 lib/merge.tcl:149 lib/merge.tcl:167
+#: git-gui.sh:2289 lib/merge.tcl:121 lib/merge.tcl:150 lib/merge.tcl:168
 msgid "Merge"
 msgstr "Fusionner"
 
-#: git-gui.sh:1958 lib/choose_rev.tcl:557
+#: git-gui.sh:2290 lib/choose_rev.tcl:557
 msgid "Remote"
 msgstr "Dépôt distant"
 
-#: git-gui.sh:1967
+#: git-gui.sh:2293
+msgid "Tools"
+msgstr "Outils"
+
+#: git-gui.sh:2302
+msgid "Explore Working Copy"
+msgstr "Explorer la copie de travail"
+
+#: git-gui.sh:2307
 msgid "Browse Current Branch's Files"
 msgstr "Naviguer dans la branche courante"
 
-#: git-gui.sh:1971
+#: git-gui.sh:2311
 msgid "Browse Branch Files..."
 msgstr "Naviguer dans la branche..."
 
-#: git-gui.sh:1976
+#: git-gui.sh:2316
 msgid "Visualize Current Branch's History"
 msgstr "Visualiser historique branche courante"
 
-#: git-gui.sh:1980
+#: git-gui.sh:2320
 msgid "Visualize All Branch History"
 msgstr "Voir l'historique de toutes les branches"
 
-#: git-gui.sh:1987
+#: git-gui.sh:2327
 #, tcl-format
 msgid "Browse %s's Files"
 msgstr "Naviguer l'arborescence de %s"
 
-#: git-gui.sh:1989
+#: git-gui.sh:2329
 #, tcl-format
 msgid "Visualize %s's History"
 msgstr "Voir l'historique de la branche: %s"
 
-#: git-gui.sh:1994 lib/database.tcl:27 lib/database.tcl:67
+#: git-gui.sh:2334 lib/database.tcl:27 lib/database.tcl:67
 msgid "Database Statistics"
 msgstr "Statistiques du dépôt"
 
-#: git-gui.sh:1997 lib/database.tcl:34
+#: git-gui.sh:2337 lib/database.tcl:34
 msgid "Compress Database"
 msgstr "Comprimer le dépôt"
 
-#: git-gui.sh:2000
+#: git-gui.sh:2340
 msgid "Verify Database"
 msgstr "Vérifier le dépôt"
 
-#: git-gui.sh:2007 git-gui.sh:2011 git-gui.sh:2015 lib/shortcut.tcl:7
+#: git-gui.sh:2347 git-gui.sh:2351 git-gui.sh:2355 lib/shortcut.tcl:7
 #: lib/shortcut.tcl:39 lib/shortcut.tcl:71
 msgid "Create Desktop Icon"
 msgstr "Créer icône sur bureau"
 
-#: git-gui.sh:2023 lib/choose_repository.tcl:177 lib/choose_repository.tcl:185
+#: git-gui.sh:2363 lib/choose_repository.tcl:183 lib/choose_repository.tcl:191
 msgid "Quit"
 msgstr "Quitter"
 
-#: git-gui.sh:2031
+#: git-gui.sh:2371
 msgid "Undo"
 msgstr "Défaire"
 
-#: git-gui.sh:2034
+#: git-gui.sh:2374
 msgid "Redo"
 msgstr "Refaire"
 
-#: git-gui.sh:2038 git-gui.sh:2545
+#: git-gui.sh:2378 git-gui.sh:2923
 msgid "Cut"
 msgstr "Couper"
 
-#: git-gui.sh:2041 git-gui.sh:2548 git-gui.sh:2622 git-gui.sh:2715
+#: git-gui.sh:2381 git-gui.sh:2926 git-gui.sh:3000 git-gui.sh:3082
 #: lib/console.tcl:69
 msgid "Copy"
 msgstr "Copier"
 
-#: git-gui.sh:2044 git-gui.sh:2551
+#: git-gui.sh:2384 git-gui.sh:2929
 msgid "Paste"
 msgstr "Coller"
 
-#: git-gui.sh:2047 git-gui.sh:2554 lib/branch_delete.tcl:26
+#: git-gui.sh:2387 git-gui.sh:2932 lib/branch_delete.tcl:26
 #: lib/remote_branch_delete.tcl:38
 msgid "Delete"
 msgstr "Supprimer"
 
-#: git-gui.sh:2051 git-gui.sh:2558 git-gui.sh:2719 lib/console.tcl:71
+#: git-gui.sh:2391 git-gui.sh:2936 git-gui.sh:3086 lib/console.tcl:71
 msgid "Select All"
 msgstr "Tout sélectionner"
 
-#: git-gui.sh:2060
+#: git-gui.sh:2400
 msgid "Create..."
 msgstr "Créer..."
 
-#: git-gui.sh:2066
+#: git-gui.sh:2406
 msgid "Checkout..."
 msgstr "Charger (checkout)..."
 
-#: git-gui.sh:2072
+#: git-gui.sh:2412
 msgid "Rename..."
 msgstr "Renommer..."
 
-#: git-gui.sh:2077 git-gui.sh:2187
+#: git-gui.sh:2417
 msgid "Delete..."
 msgstr "Supprimer..."
 
-#: git-gui.sh:2082
+#: git-gui.sh:2422
 msgid "Reset..."
 msgstr "Réinitialiser..."
 
-#: git-gui.sh:2094 git-gui.sh:2491
+#: git-gui.sh:2432
+msgid "Done"
+msgstr "Effectué"
+
+#: git-gui.sh:2434
+msgid "Commit@@verb"
+msgstr "Commiter@@verb"
+
+#: git-gui.sh:2443 git-gui.sh:2864
 msgid "New Commit"
 msgstr "Nouveau commit"
 
-#: git-gui.sh:2102 git-gui.sh:2498
+#: git-gui.sh:2451 git-gui.sh:2871
 msgid "Amend Last Commit"
 msgstr "Corriger dernier commit"
 
-#: git-gui.sh:2111 git-gui.sh:2458 lib/remote_branch_delete.tcl:99
+#: git-gui.sh:2461 git-gui.sh:2825 lib/remote_branch_delete.tcl:99
 msgid "Rescan"
 msgstr "Recharger modifs."
 
-#: git-gui.sh:2117
+#: git-gui.sh:2467
 msgid "Stage To Commit"
 msgstr "Indexer"
 
-#: git-gui.sh:2123
+#: git-gui.sh:2473
 msgid "Stage Changed Files To Commit"
 msgstr "Indexer toutes modifications"
 
-#: git-gui.sh:2129
+#: git-gui.sh:2479
 msgid "Unstage From Commit"
 msgstr "Désindexer"
 
-#: git-gui.sh:2134 lib/index.tcl:395
+#: git-gui.sh:2484 lib/index.tcl:410
 msgid "Revert Changes"
 msgstr "Annuler les modifications (revert)"
 
-#: git-gui.sh:2141 git-gui.sh:2702
+#: git-gui.sh:2491 git-gui.sh:3069
 msgid "Show Less Context"
 msgstr "Montrer moins de contexte"
 
-#: git-gui.sh:2145 git-gui.sh:2706
+#: git-gui.sh:2495 git-gui.sh:3073
 msgid "Show More Context"
 msgstr "Montrer plus de contexte"
 
-#: git-gui.sh:2151 git-gui.sh:2470 git-gui.sh:2569
+#: git-gui.sh:2502 git-gui.sh:2838 git-gui.sh:2947
 msgid "Sign Off"
 msgstr "Signer"
 
-#: git-gui.sh:2155 git-gui.sh:2474
-msgid "Commit@@verb"
-msgstr "Commiter"
-
-#: git-gui.sh:2166
+#: git-gui.sh:2518
 msgid "Local Merge..."
 msgstr "Fusion locale..."
 
-#: git-gui.sh:2171
+#: git-gui.sh:2523
 msgid "Abort Merge..."
 msgstr "Abandonner fusion..."
 
-#: git-gui.sh:2183
+#: git-gui.sh:2535 git-gui.sh:2575
+msgid "Add..."
+msgstr "Ajouter..."
+
+#: git-gui.sh:2539
 msgid "Push..."
 msgstr "Pousser..."
 
-#: git-gui.sh:2197 git-gui.sh:2219 lib/about.tcl:14
-#: lib/choose_repository.tcl:44 lib/choose_repository.tcl:50
+#: git-gui.sh:2543
+msgid "Delete Branch..."
+msgstr "Supprimer branche..."
+
+#: git-gui.sh:2553 git-gui.sh:2589 lib/about.tcl:14
+#: lib/choose_repository.tcl:44 lib/choose_repository.tcl:53
 #, tcl-format
 msgid "About %s"
 msgstr "À propos de %s"
 
-#: git-gui.sh:2201
+#: git-gui.sh:2557
 msgid "Preferences..."
 msgstr "Préférences..."
 
-#: git-gui.sh:2209 git-gui.sh:2740
+#: git-gui.sh:2565 git-gui.sh:3115
 msgid "Options..."
 msgstr "Options..."
 
-#: git-gui.sh:2215 lib/choose_repository.tcl:47
+#: git-gui.sh:2576
+msgid "Remove..."
+msgstr "Supprimer..."
+
+#: git-gui.sh:2585 lib/choose_repository.tcl:50
 msgid "Help"
 msgstr "Aide"
 
-#: git-gui.sh:2256
+#: git-gui.sh:2611
 msgid "Online Documentation"
 msgstr "Documentation en ligne"
 
-#: git-gui.sh:2340
+#: git-gui.sh:2614 lib/choose_repository.tcl:47 lib/choose_repository.tcl:56
+msgid "Show SSH Key"
+msgstr "Montrer clé SSH"
+
+#: git-gui.sh:2707
 #, tcl-format
 msgid "fatal: cannot stat path %s: No such file or directory"
 msgstr ""
 "erreur fatale : pas d'infos sur le chemin %s : Fichier ou répertoire "
 "inexistant"
 
-#: git-gui.sh:2373
+#: git-gui.sh:2740
 msgid "Current Branch:"
 msgstr "Branche courante :"
 
-#: git-gui.sh:2394
+#: git-gui.sh:2761
 msgid "Staged Changes (Will Commit)"
 msgstr "Modifs. indexées (pour commit)"
 
-#: git-gui.sh:2414
+#: git-gui.sh:2781
 msgid "Unstaged Changes"
 msgstr "Modifs. non indexées"
 
-#: git-gui.sh:2464
+#: git-gui.sh:2831
 msgid "Stage Changed"
 msgstr "Indexer modifs."
 
-#: git-gui.sh:2480 lib/transport.tcl:93 lib/transport.tcl:182
+#: git-gui.sh:2850 lib/transport.tcl:93 lib/transport.tcl:182
 msgid "Push"
 msgstr "Pousser"
 
-#: git-gui.sh:2510
+#: git-gui.sh:2885
 msgid "Initial Commit Message:"
 msgstr "Message de commit initial :"
 
-#: git-gui.sh:2511
+#: git-gui.sh:2886
 msgid "Amended Commit Message:"
 msgstr "Message de commit corrigé :"
 
-#: git-gui.sh:2512
+#: git-gui.sh:2887
 msgid "Amended Initial Commit Message:"
 msgstr "Message de commit initial corrigé :"
 
-#: git-gui.sh:2513
+#: git-gui.sh:2888
 msgid "Amended Merge Commit Message:"
 msgstr "Message de commit de fusion corrigé :"
 
-#: git-gui.sh:2514
+#: git-gui.sh:2889
 msgid "Merge Commit Message:"
 msgstr "Message de commit de fusion :"
 
-#: git-gui.sh:2515
+#: git-gui.sh:2890
 msgid "Commit Message:"
 msgstr "Message de commit :"
 
-#: git-gui.sh:2561 git-gui.sh:2723 lib/console.tcl:73
+#: git-gui.sh:2939 git-gui.sh:3090 lib/console.tcl:73
 msgid "Copy All"
 msgstr "Copier tout"
 
-#: git-gui.sh:2585 lib/blame.tcl:100
+#: git-gui.sh:2963 lib/blame.tcl:104
 msgid "File:"
 msgstr "Fichier :"
 
-#: git-gui.sh:2691
-msgid "Apply/Reverse Hunk"
-msgstr "Appliquer/Inverser section"
-
-#: git-gui.sh:2696
-msgid "Apply/Reverse Line"
-msgstr "Appliquer/Inverser la ligne"
-
-#: git-gui.sh:2711
+#: git-gui.sh:3078
 msgid "Refresh"
 msgstr "Rafraichir"
 
-#: git-gui.sh:2732
+#: git-gui.sh:3099
 msgid "Decrease Font Size"
 msgstr "Diminuer la police"
 
-#: git-gui.sh:2736
+#: git-gui.sh:3103
 msgid "Increase Font Size"
 msgstr "Agrandir la police"
 
-#: git-gui.sh:2747
+#: git-gui.sh:3111 lib/blame.tcl:281
+msgid "Encoding"
+msgstr "Encodage"
+
+#: git-gui.sh:3122
+msgid "Apply/Reverse Hunk"
+msgstr "Appliquer/Inverser section"
+
+#: git-gui.sh:3127
+msgid "Apply/Reverse Line"
+msgstr "Appliquer/Inverser la ligne"
+
+#: git-gui.sh:3137
+msgid "Run Merge Tool"
+msgstr "Lancer outil de merge"
+
+#: git-gui.sh:3142
+msgid "Use Remote Version"
+msgstr "Utiliser la version distante"
+
+#: git-gui.sh:3146
+msgid "Use Local Version"
+msgstr "Utiliser la version locale"
+
+#: git-gui.sh:3150
+msgid "Revert To Base"
+msgstr "Revenir à la version de base"
+
+#: git-gui.sh:3169
 msgid "Unstage Hunk From Commit"
 msgstr "Désindexer la section"
 
-#: git-gui.sh:2748
+#: git-gui.sh:3170
 msgid "Unstage Line From Commit"
 msgstr "Désindexer la ligne"
 
-#: git-gui.sh:2750
+#: git-gui.sh:3172
 msgid "Stage Hunk For Commit"
 msgstr "Indexer la section"
 
-#: git-gui.sh:2751
+#: git-gui.sh:3173
 msgid "Stage Line For Commit"
 msgstr "Indexer la ligne"
 
-#: git-gui.sh:2771
+#: git-gui.sh:3196
 msgid "Initializing..."
 msgstr "Initialisation..."
 
-#: git-gui.sh:2876
+#: git-gui.sh:3301
 #, tcl-format
 msgid ""
 "Possible environment issues exist.\n"
@@ -455,7 +520,7 @@ msgstr ""
 "sous-processus de Git lancés par %s\n"
 "\n"
 
-#: git-gui.sh:2906
+#: git-gui.sh:3331
 msgid ""
 "\n"
 "This is due to a known issue with the\n"
@@ -465,7 +530,7 @@ msgstr ""
 "Ceci est du à un problème connu avec\n"
 "le binaire Tcl distribué par Cygwin."
 
-#: git-gui.sh:2911
+#: git-gui.sh:3336
 #, tcl-format
 msgid ""
 "\n"
@@ -486,80 +551,108 @@ msgstr ""
 msgid "git-gui - a graphical user interface for Git."
 msgstr "git-gui - une interface graphique utilisateur pour Git"
 
-#: lib/blame.tcl:70
+#: lib/blame.tcl:72
 msgid "File Viewer"
 msgstr "Visionneur de fichier"
 
-#: lib/blame.tcl:74
+#: lib/blame.tcl:78
 msgid "Commit:"
 msgstr "Commit :"
 
-#: lib/blame.tcl:257
+#: lib/blame.tcl:271
 msgid "Copy Commit"
 msgstr "Copier commit"
 
-#: lib/blame.tcl:260
+#: lib/blame.tcl:275
+msgid "Find Text..."
+msgstr "Chercher texte..."
+
+#: lib/blame.tcl:284
 msgid "Do Full Copy Detection"
 msgstr "Lancer la détection approfondie des copies"
 
-#: lib/blame.tcl:388
+#: lib/blame.tcl:288
+msgid "Show History Context"
+msgstr "Montrer l'historique"
+
+#: lib/blame.tcl:291
+msgid "Blame Parent Commit"
+msgstr "Blâmer le commit parent"
+
+#: lib/blame.tcl:450
 #, tcl-format
 msgid "Reading %s..."
 msgstr "Lecture de %s..."
 
-#: lib/blame.tcl:492
+#: lib/blame.tcl:557
 msgid "Loading copy/move tracking annotations..."
 msgstr "Chargement des annotations de suivi des copies/déplacements..."
 
-#: lib/blame.tcl:512
+#: lib/blame.tcl:577
 msgid "lines annotated"
 msgstr "lignes annotées"
 
-#: lib/blame.tcl:704
+#: lib/blame.tcl:769
 msgid "Loading original location annotations..."
 msgstr "Chargement des annotations d'emplacement original"
 
-#: lib/blame.tcl:707
+#: lib/blame.tcl:772
 msgid "Annotation complete."
 msgstr "Annotation terminée."
 
-#: lib/blame.tcl:737
+#: lib/blame.tcl:802
 msgid "Busy"
 msgstr "Occupé"
 
-#: lib/blame.tcl:738
+#: lib/blame.tcl:803
 msgid "Annotation process is already running."
 msgstr "Annotation en cours d'exécution."
 
-#: lib/blame.tcl:777
+#: lib/blame.tcl:842
 msgid "Running thorough copy detection..."
 msgstr "Recherche de copie approfondie en cours..."
 
-#: lib/blame.tcl:827
+#: lib/blame.tcl:910
 msgid "Loading annotation..."
 msgstr "Chargement des annotations..."
 
-#: lib/blame.tcl:883
+#: lib/blame.tcl:964
 msgid "Author:"
 msgstr "Auteur :"
 
-#: lib/blame.tcl:887
+#: lib/blame.tcl:968
 msgid "Committer:"
 msgstr "Commiteur :"
 
-#: lib/blame.tcl:892
+#: lib/blame.tcl:973
 msgid "Original File:"
 msgstr "Fichier original :"
 
-#: lib/blame.tcl:1006
+#: lib/blame.tcl:1021
+msgid "Cannot find HEAD commit:"
+msgstr "Impossible de trouver le commit HEAD:"
+
+#: lib/blame.tcl:1076
+msgid "Cannot find parent commit:"
+msgstr "Impossible de trouver le commit parent:"
+
+#: lib/blame.tcl:1091
+msgid "Unable to display parent"
+msgstr "Impossible d'afficher le parent"
+
+#: lib/blame.tcl:1092 lib/diff.tcl:297
+msgid "Error loading diff:"
+msgstr "Erreur lors du chargement des différences :"
+
+#: lib/blame.tcl:1232
 msgid "Originally By:"
 msgstr "A l'origine par :"
 
-#: lib/blame.tcl:1012
+#: lib/blame.tcl:1238
 msgid "In File:"
 msgstr "Dans le fichier :"
 
-#: lib/blame.tcl:1017
+#: lib/blame.tcl:1243
 msgid "Copied Or Moved Here By:"
 msgstr "Copié ou déplacé ici par :"
 
@@ -573,16 +666,18 @@ msgstr "Charger (checkout)"
 
 #: lib/branch_checkout.tcl:27 lib/branch_create.tcl:35
 #: lib/branch_delete.tcl:32 lib/branch_rename.tcl:30 lib/browser.tcl:282
-#: lib/checkout_op.tcl:544 lib/choose_font.tcl:43 lib/merge.tcl:171
-#: lib/option.tcl:103 lib/remote_branch_delete.tcl:42 lib/transport.tcl:97
+#: lib/checkout_op.tcl:544 lib/choose_font.tcl:43 lib/merge.tcl:172
+#: lib/option.tcl:125 lib/remote_add.tcl:32 lib/remote_branch_delete.tcl:42
+#: lib/tools_dlg.tcl:40 lib/tools_dlg.tcl:204 lib/tools_dlg.tcl:352
+#: lib/transport.tcl:97
 msgid "Cancel"
 msgstr "Annuler"
 
-#: lib/branch_checkout.tcl:32 lib/browser.tcl:287
+#: lib/branch_checkout.tcl:32 lib/browser.tcl:287 lib/tools_dlg.tcl:328
 msgid "Revision"
 msgstr "Révision"
 
-#: lib/branch_checkout.tcl:36 lib/branch_create.tcl:69 lib/option.tcl:244
+#: lib/branch_checkout.tcl:36 lib/branch_create.tcl:69 lib/option.tcl:280
 msgid "Options"
 msgstr "Options"
 
@@ -602,7 +697,7 @@ msgstr "Créer branche"
 msgid "Create New Branch"
 msgstr "Créer nouvelle branche"
 
-#: lib/branch_create.tcl:31 lib/choose_repository.tcl:371
+#: lib/branch_create.tcl:31 lib/choose_repository.tcl:377
 msgid "Create"
 msgstr "Créer"
 
@@ -610,7 +705,7 @@ msgstr "Créer"
 msgid "Branch Name"
 msgstr "Nom de branche"
 
-#: lib/branch_create.tcl:43
+#: lib/branch_create.tcl:43 lib/remote_add.tcl:39 lib/tools_dlg.tcl:50
 msgid "Name:"
 msgstr "Nom :"
 
@@ -755,9 +850,9 @@ msgstr "[Jusqu'au parent]"
 msgid "Browse Branch Files"
 msgstr "Naviguer dans les fichiers de le branche"
 
-#: lib/browser.tcl:278 lib/choose_repository.tcl:387
-#: lib/choose_repository.tcl:472 lib/choose_repository.tcl:482
-#: lib/choose_repository.tcl:985
+#: lib/browser.tcl:278 lib/choose_repository.tcl:394
+#: lib/choose_repository.tcl:480 lib/choose_repository.tcl:491
+#: lib/choose_repository.tcl:995
 msgid "Browse"
 msgstr "Naviguer"
 
@@ -772,6 +867,7 @@ msgid "fatal: Cannot resolve %s"
 msgstr "erreur fatale : Impossible de résoudre %s"
 
 #: lib/checkout_op.tcl:145 lib/console.tcl:81 lib/database.tcl:31
+#: lib/sshkey.tcl:53
 msgid "Close"
 msgstr "Fermer"
 
@@ -884,7 +980,7 @@ msgstr "Récupérer les commits perdus ne sera peut être pas facile."
 msgid "Reset '%s'?"
 msgstr "Réinitialiser '%s' ?"
 
-#: lib/checkout_op.tcl:532 lib/merge.tcl:163
+#: lib/checkout_op.tcl:532 lib/merge.tcl:164 lib/tools_dlg.tcl:343
 msgid "Visualize"
 msgstr "Visualiser"
 
@@ -934,225 +1030,229 @@ msgstr ""
 msgid "Git Gui"
 msgstr "Git Gui"
 
-#: lib/choose_repository.tcl:81 lib/choose_repository.tcl:376
+#: lib/choose_repository.tcl:87 lib/choose_repository.tcl:382
 msgid "Create New Repository"
 msgstr "Créer nouveau dépôt"
 
-#: lib/choose_repository.tcl:87
+#: lib/choose_repository.tcl:93
 msgid "New..."
 msgstr "Nouveau..."
 
-#: lib/choose_repository.tcl:94 lib/choose_repository.tcl:458
+#: lib/choose_repository.tcl:100 lib/choose_repository.tcl:465
 msgid "Clone Existing Repository"
 msgstr "Cloner dépôt existant"
 
-#: lib/choose_repository.tcl:100
+#: lib/choose_repository.tcl:106
 msgid "Clone..."
 msgstr "Cloner..."
 
-#: lib/choose_repository.tcl:107 lib/choose_repository.tcl:974
+#: lib/choose_repository.tcl:113 lib/choose_repository.tcl:983
 msgid "Open Existing Repository"
 msgstr "Ouvrir dépôt existant"
 
-#: lib/choose_repository.tcl:113
+#: lib/choose_repository.tcl:119
 msgid "Open..."
 msgstr "Ouvrir..."
 
-#: lib/choose_repository.tcl:126
+#: lib/choose_repository.tcl:132
 msgid "Recent Repositories"
 msgstr "Dépôt récemment utilisés"
 
-#: lib/choose_repository.tcl:132
+#: lib/choose_repository.tcl:138
 msgid "Open Recent Repository:"
 msgstr "Ouvrir dépôt récent :"
 
-#: lib/choose_repository.tcl:296 lib/choose_repository.tcl:303
-#: lib/choose_repository.tcl:310
+#: lib/choose_repository.tcl:302 lib/choose_repository.tcl:309
+#: lib/choose_repository.tcl:316
 #, tcl-format
 msgid "Failed to create repository %s:"
 msgstr "La création du dépôt %s a échouée :"
 
-#: lib/choose_repository.tcl:381 lib/choose_repository.tcl:476
+#: lib/choose_repository.tcl:387
 msgid "Directory:"
 msgstr "Répertoire :"
 
-#: lib/choose_repository.tcl:410 lib/choose_repository.tcl:535
-#: lib/choose_repository.tcl:1007
+#: lib/choose_repository.tcl:417 lib/choose_repository.tcl:544
+#: lib/choose_repository.tcl:1017
 msgid "Git Repository"
 msgstr "Dépôt Git"
 
-#: lib/choose_repository.tcl:435
+#: lib/choose_repository.tcl:442
 #, tcl-format
 msgid "Directory %s already exists."
 msgstr "Le répertoire %s existe déjà."
 
-#: lib/choose_repository.tcl:439
+#: lib/choose_repository.tcl:446
 #, tcl-format
 msgid "File %s already exists."
 msgstr "Le fichier %s existe déjà."
 
-#: lib/choose_repository.tcl:453
+#: lib/choose_repository.tcl:460
 msgid "Clone"
 msgstr "Cloner"
 
-#: lib/choose_repository.tcl:466
-msgid "URL:"
-msgstr "URL :"
+#: lib/choose_repository.tcl:473
+msgid "Source Location:"
+msgstr "Emplacement source:"
 
-#: lib/choose_repository.tcl:487
+#: lib/choose_repository.tcl:484
+msgid "Target Directory:"
+msgstr "Répertoire cible:"
+
+#: lib/choose_repository.tcl:496
 msgid "Clone Type:"
 msgstr "Type de clonage :"
 
-#: lib/choose_repository.tcl:493
+#: lib/choose_repository.tcl:502
 msgid "Standard (Fast, Semi-Redundant, Hardlinks)"
 msgstr "Standard (rapide, semi-redondant, liens durs)"
 
-#: lib/choose_repository.tcl:499
+#: lib/choose_repository.tcl:508
 msgid "Full Copy (Slower, Redundant Backup)"
 msgstr "Copy complète (plus lent, sauvegarde redondante)"
 
-#: lib/choose_repository.tcl:505
+#: lib/choose_repository.tcl:514
 msgid "Shared (Fastest, Not Recommended, No Backup)"
 msgstr "Partagé (le plus rapide, non recommandé, pas de sauvegarde)"
 
-#: lib/choose_repository.tcl:541 lib/choose_repository.tcl:588
-#: lib/choose_repository.tcl:734 lib/choose_repository.tcl:804
-#: lib/choose_repository.tcl:1013 lib/choose_repository.tcl:1021
+#: lib/choose_repository.tcl:550 lib/choose_repository.tcl:597
+#: lib/choose_repository.tcl:743 lib/choose_repository.tcl:813
+#: lib/choose_repository.tcl:1023 lib/choose_repository.tcl:1031
 #, tcl-format
 msgid "Not a Git repository: %s"
 msgstr "'%s' n'est pas un dépôt Git."
 
-#: lib/choose_repository.tcl:577
+#: lib/choose_repository.tcl:586
 msgid "Standard only available for local repository."
 msgstr "Standard n'est disponible que pour un dépôt local."
 
-#: lib/choose_repository.tcl:581
+#: lib/choose_repository.tcl:590
 msgid "Shared only available for local repository."
 msgstr "Partagé n'est disponible que pour un dépôt local."
 
-#: lib/choose_repository.tcl:602
+#: lib/choose_repository.tcl:611
 #, tcl-format
 msgid "Location %s already exists."
 msgstr "L'emplacement %s existe déjà."
 
-#: lib/choose_repository.tcl:613
+#: lib/choose_repository.tcl:622
 msgid "Failed to configure origin"
 msgstr "La configuration de l'origine a échouée."
 
-#: lib/choose_repository.tcl:625
+#: lib/choose_repository.tcl:634
 msgid "Counting objects"
 msgstr "Décompte des objets"
 
-#: lib/choose_repository.tcl:626
+#: lib/choose_repository.tcl:635
 msgid "buckets"
 msgstr "paniers"
 
-#: lib/choose_repository.tcl:650
+#: lib/choose_repository.tcl:659
 #, tcl-format
 msgid "Unable to copy objects/info/alternates: %s"
 msgstr "Impossible de copier 'objects/info/alternates' : %s"
 
-#: lib/choose_repository.tcl:686
+#: lib/choose_repository.tcl:695
 #, tcl-format
 msgid "Nothing to clone from %s."
 msgstr "Il n'y a rien à cloner depuis %s."
 
-#: lib/choose_repository.tcl:688 lib/choose_repository.tcl:902
-#: lib/choose_repository.tcl:914
+#: lib/choose_repository.tcl:697 lib/choose_repository.tcl:911
+#: lib/choose_repository.tcl:923
 msgid "The 'master' branch has not been initialized."
 msgstr "La branche 'master' n'a pas été initialisée."
 
-#: lib/choose_repository.tcl:701
+#: lib/choose_repository.tcl:710
 msgid "Hardlinks are unavailable.  Falling back to copying."
 msgstr "Les liens durs ne sont pas supportés. Une copie sera effectuée à la place."
 
-#: lib/choose_repository.tcl:713
+#: lib/choose_repository.tcl:722
 #, tcl-format
 msgid "Cloning from %s"
 msgstr "Clonage depuis %s"
 
-#: lib/choose_repository.tcl:744
+#: lib/choose_repository.tcl:753
 msgid "Copying objects"
 msgstr "Copie des objets"
 
-#: lib/choose_repository.tcl:745
+#: lib/choose_repository.tcl:754
 msgid "KiB"
 msgstr "KiB"
 
-#: lib/choose_repository.tcl:769
+#: lib/choose_repository.tcl:778
 #, tcl-format
 msgid "Unable to copy object: %s"
 msgstr "Impossible de copier l'objet : %s"
 
-#: lib/choose_repository.tcl:779
+#: lib/choose_repository.tcl:788
 msgid "Linking objects"
 msgstr "Liaison des objets"
 
-#: lib/choose_repository.tcl:780
+#: lib/choose_repository.tcl:789
 msgid "objects"
 msgstr "objets"
 
-#: lib/choose_repository.tcl:788
+#: lib/choose_repository.tcl:797
 #, tcl-format
 msgid "Unable to hardlink object: %s"
 msgstr "Impossible créer un lien dur pour l'objet : %s"
 
-#: lib/choose_repository.tcl:843
+#: lib/choose_repository.tcl:852
 msgid "Cannot fetch branches and objects.  See console output for details."
 msgstr ""
 "Impossible de récupérer les branches et objets. Voir la sortie console pour "
 "plus de détails."
 
-#: lib/choose_repository.tcl:854
+#: lib/choose_repository.tcl:863
 msgid "Cannot fetch tags.  See console output for details."
 msgstr ""
 "Impossible de récupérer les marques (tags). Voir la sortie console pour plus "
 "de détails."
 
-#: lib/choose_repository.tcl:878
+#: lib/choose_repository.tcl:887
 msgid "Cannot determine HEAD.  See console output for details."
 msgstr "Impossible de déterminer HEAD. Voir la sortie console pour plus de détails."
 
-#: lib/choose_repository.tcl:887
+#: lib/choose_repository.tcl:896
 #, tcl-format
 msgid "Unable to cleanup %s"
 msgstr "Impossible de nettoyer %s"
 
-#: lib/choose_repository.tcl:893
+#: lib/choose_repository.tcl:902
 msgid "Clone failed."
 msgstr "Le clonage a échoué."
 
-#: lib/choose_repository.tcl:900
+#: lib/choose_repository.tcl:909
 msgid "No default branch obtained."
 msgstr "Aucune branche par défaut n'a été obtenue."
 
-#: lib/choose_repository.tcl:911
+#: lib/choose_repository.tcl:920
 #, tcl-format
 msgid "Cannot resolve %s as a commit."
 msgstr "Impossible de résoudre %s comme commit."
 
-#: lib/choose_repository.tcl:923
+#: lib/choose_repository.tcl:932
 msgid "Creating working directory"
 msgstr "Création du répertoire de travail"
 
-#: lib/choose_repository.tcl:924 lib/index.tcl:65 lib/index.tcl:127
-#: lib/index.tcl:193
+#: lib/choose_repository.tcl:933 lib/index.tcl:65 lib/index.tcl:128
+#: lib/index.tcl:196
 msgid "files"
 msgstr "fichiers"
 
-#: lib/choose_repository.tcl:953
+#: lib/choose_repository.tcl:962
 msgid "Initial file checkout failed."
 msgstr "Chargement initial du fichier échoué."
 
-#: lib/choose_repository.tcl:969
+#: lib/choose_repository.tcl:978
 msgid "Open"
 msgstr "Ouvrir"
 
-#: lib/choose_repository.tcl:979
+#: lib/choose_repository.tcl:988
 msgid "Repository:"
 msgstr "Dépôt :"
 
-#: lib/choose_repository.tcl:1027
+#: lib/choose_repository.tcl:1037
 #, tcl-format
 msgid "Failed to open repository %s:"
 msgstr "Impossible d'ouvrir le dépôt %s :"
@@ -1254,7 +1354,7 @@ msgstr ""
 "\n"
 "Cela va être fait tout de suite automatiquement.\n"
 
-#: lib/commit.tcl:154
+#: lib/commit.tcl:156
 #, tcl-format
 msgid ""
 "Unmerged files cannot be committed.\n"
@@ -1267,7 +1367,7 @@ msgstr ""
 "Le fichier %s a des conflicts de fusion. Vous devez les résoudre et pré-"
 "commiter le fichier avant de pouvoir commiter.\n"
 
-#: lib/commit.tcl:162
+#: lib/commit.tcl:164
 #, tcl-format
 msgid ""
 "Unknown file state %s detected.\n"
@@ -1278,7 +1378,7 @@ msgstr ""
 "\n"
 "Le fichier %s ne peut pas être commité par ce programme.\n"
 
-#: lib/commit.tcl:170
+#: lib/commit.tcl:172
 msgid ""
 "No changes to commit.\n"
 "\n"
@@ -1288,7 +1388,7 @@ msgstr ""
 "\n"
 "Vous devez indexer au moins 1 fichier avant de pouvoir commiter.\n"
 
-#: lib/commit.tcl:183
+#: lib/commit.tcl:187
 msgid ""
 "Please supply a commit message.\n"
 "\n"
@@ -1306,45 +1406,45 @@ msgstr ""
 "- Deuxième ligne : rien.\n"
 "- Lignes suivantes : Décrire pourquoi ces modifications sont bonnes.\n"
 
-#: lib/commit.tcl:207
+#: lib/commit.tcl:211
 #, tcl-format
 msgid "warning: Tcl does not support encoding '%s'."
 msgstr "attention : Tcl ne supporte pas l'encodage '%s'."
 
-#: lib/commit.tcl:221
+#: lib/commit.tcl:227
 msgid "Calling pre-commit hook..."
 msgstr "Lancement de l'action d'avant-commit..."
 
-#: lib/commit.tcl:236
+#: lib/commit.tcl:242
 msgid "Commit declined by pre-commit hook."
 msgstr "Commit refusé par l'action d'avant-commit."
 
-#: lib/commit.tcl:259
+#: lib/commit.tcl:265
 msgid "Calling commit-msg hook..."
 msgstr "Lancement de l'action \"message de commit\"..."
 
-#: lib/commit.tcl:274
+#: lib/commit.tcl:280
 msgid "Commit declined by commit-msg hook."
 msgstr "Commit refusé par l'action \"message de commit\"."
 
-#: lib/commit.tcl:287
+#: lib/commit.tcl:293
 msgid "Committing changes..."
 msgstr "Commit des modifications..."
 
-#: lib/commit.tcl:303
+#: lib/commit.tcl:309
 msgid "write-tree failed:"
 msgstr "write-tree a échoué :"
 
-#: lib/commit.tcl:304 lib/commit.tcl:348 lib/commit.tcl:368
+#: lib/commit.tcl:310 lib/commit.tcl:354 lib/commit.tcl:374
 msgid "Commit failed."
 msgstr "Le commit a échoué."
 
-#: lib/commit.tcl:321
+#: lib/commit.tcl:327
 #, tcl-format
 msgid "Commit %s appears to be corrupt"
 msgstr "Le commit %s semble être corrompu"
 
-#: lib/commit.tcl:326
+#: lib/commit.tcl:332
 msgid ""
 "No changes to commit.\n"
 "\n"
@@ -1359,19 +1459,19 @@ msgstr ""
 "\n"
 "Une resynchronisation va être lancée tout de suite automatiquement.\n"
 
-#: lib/commit.tcl:333
+#: lib/commit.tcl:339
 msgid "No changes to commit."
 msgstr "Pas de modifications à commiter."
 
-#: lib/commit.tcl:347
+#: lib/commit.tcl:353
 msgid "commit-tree failed:"
 msgstr "commit-tree a échoué :"
 
-#: lib/commit.tcl:367
+#: lib/commit.tcl:373
 msgid "update-ref failed:"
 msgstr "update-ref a échoué"
 
-#: lib/commit.tcl:454
+#: lib/commit.tcl:461
 #, tcl-format
 msgid "Created commit %s: %s"
 msgstr "Commit créé %s : %s"
@@ -1448,7 +1548,7 @@ msgstr ""
 msgid "Invalid date from Git: %s"
 msgstr "Date invalide de Git : %s"
 
-#: lib/diff.tcl:44
+#: lib/diff.tcl:59
 #, tcl-format
 msgid ""
 "No differences detected.\n"
@@ -1471,48 +1571,101 @@ msgstr ""
 "Une resynchronisation va être lancée automatiquement pour trouver d'autres "
 "fichiers qui pourraient se trouver dans le même état."
 
-#: lib/diff.tcl:83
+#: lib/diff.tcl:99
 #, tcl-format
 msgid "Loading diff of %s..."
 msgstr "Chargement des différences de %s..."
 
-#: lib/diff.tcl:116 lib/diff.tcl:190
+#: lib/diff.tcl:120
+msgid ""
+"LOCAL: deleted\n"
+"REMOTE:\n"
+msgstr ""
+"LOCAL: supprimé\n"
+"DISTANT:\n"
+
+#: lib/diff.tcl:125
+msgid ""
+"REMOTE: deleted\n"
+"LOCAL:\n"
+msgstr ""
+"DISTANT: supprimé\n"
+"LOCAL:\n"
+
+#: lib/diff.tcl:132
+msgid "LOCAL:\n"
+msgstr "LOCAL:\n"
+
+#: lib/diff.tcl:135
+msgid "REMOTE:\n"
+msgstr "DISTANT:\n"
+
+#: lib/diff.tcl:197 lib/diff.tcl:296
 #, tcl-format
 msgid "Unable to display %s"
 msgstr "Impossible d'afficher %s"
 
-#: lib/diff.tcl:117
+#: lib/diff.tcl:198
 msgid "Error loading file:"
 msgstr "Erreur lors du chargement du fichier :"
 
-#: lib/diff.tcl:124
+#: lib/diff.tcl:205
 msgid "Git Repository (subproject)"
 msgstr "Dépôt Git (sous projet)"
 
-#: lib/diff.tcl:136
+#: lib/diff.tcl:217
 msgid "* Binary file (not showing content)."
 msgstr "* Fichier binaire (pas d'apperçu du contenu)."
 
-#: lib/diff.tcl:191
-msgid "Error loading diff:"
-msgstr "Erreur lors du chargement des différences :"
+#: lib/diff.tcl:222
+#, tcl-format
+msgid ""
+"* Untracked file is %d bytes.\n"
+"* Showing only first %d bytes.\n"
+msgstr ""
+"* Le fichier non suivi fait %d octets.\n"
+"* On montre seulement les premiers %d octets.\n"
 
-#: lib/diff.tcl:313
+#: lib/diff.tcl:228
+#, tcl-format
+msgid ""
+"\n"
+"* Untracked file clipped here by %s.\n"
+"* To see the entire file, use an external editor.\n"
+msgstr ""
+"\n"
+"* Fichier suivi raccourcis ici de %s.\n"
+"* Pour voir le fichier entier, utiliser un éditeur externe.\n"
+
+#: lib/diff.tcl:436
 msgid "Failed to unstage selected hunk."
 msgstr "Échec lors de la désindexation de la section sélectionnée."
 
-#: lib/diff.tcl:320
+#: lib/diff.tcl:443
 msgid "Failed to stage selected hunk."
 msgstr "Échec lors de l'indexation de la section."
 
-#: lib/diff.tcl:386
+#: lib/diff.tcl:509
 msgid "Failed to unstage selected line."
 msgstr "Échec lors de la désindexation de la ligne sélectionnée."
 
-#: lib/diff.tcl:394
+#: lib/diff.tcl:517
 msgid "Failed to stage selected line."
 msgstr "Échec lors de l'indexation de la ligne."
 
+#: lib/encoding.tcl:443
+msgid "Default"
+msgstr "Défaut"
+
+#: lib/encoding.tcl:448
+#, tcl-format
+msgid "System (%s)"
+msgstr "Système (%s)"
+
+#: lib/encoding.tcl:459 lib/encoding.tcl:465
+msgid "Other"
+msgstr "Autre"
+
 #: lib/error.tcl:20 lib/error.tcl:114
 msgid "error"
 msgstr "erreur"
@@ -1549,40 +1702,49 @@ msgstr "Continuer"
 msgid "Unlock Index"
 msgstr "Déverouiller l'index"
 
-#: lib/index.tcl:282
+#: lib/index.tcl:287
 #, tcl-format
 msgid "Unstaging %s from commit"
 msgstr "Désindexation de: %s"
 
-#: lib/index.tcl:313
+#: lib/index.tcl:326
 msgid "Ready to commit."
 msgstr "Prêt à être commité."
 
-#: lib/index.tcl:326
+#: lib/index.tcl:339
 #, tcl-format
 msgid "Adding %s"
 msgstr "Ajout de %s"
 
-#: lib/index.tcl:381
+#: lib/index.tcl:396
 #, tcl-format
 msgid "Revert changes in file %s?"
 msgstr "Annuler les modifications dans le fichier %s ? "
 
-#: lib/index.tcl:383
+#: lib/index.tcl:398
 #, tcl-format
 msgid "Revert changes in these %i files?"
 msgstr "Annuler les modifications dans ces %i fichiers ?"
 
-#: lib/index.tcl:391
+#: lib/index.tcl:406
 msgid "Any unstaged changes will be permanently lost by the revert."
 msgstr ""
 "Toutes les modifications non-indexées seront définitivement perdues par "
 "l'annulation."
 
-#: lib/index.tcl:394
+#: lib/index.tcl:409
 msgid "Do Nothing"
 msgstr "Ne rien faire"
 
+#: lib/index.tcl:427
+msgid "Reverting selected files"
+msgstr "Annuler modifications dans fichiers selectionnés"
+
+#: lib/index.tcl:431
+#, tcl-format
+msgid "Reverting %s"
+msgstr "Annulation des modifications dans %s"
+
 #: lib/merge.tcl:13
 msgid ""
 "Cannot merge while amending.\n"
@@ -1612,7 +1774,7 @@ msgstr ""
 "\n"
 "Cela va être fait tout de suite automatiquement\n"
 
-#: lib/merge.tcl:44
+#: lib/merge.tcl:45
 #, tcl-format
 msgid ""
 "You are in the middle of a conflicted merge.\n"
@@ -1630,7 +1792,7 @@ msgstr ""
 "terminer la fusion courante. Seulement à ce moment là sera-t-il possible "
 "d'effectuer une nouvelle fusion.\n"
 
-#: lib/merge.tcl:54
+#: lib/merge.tcl:55
 #, tcl-format
 msgid ""
 "You are in the middle of a change.\n"
@@ -1648,34 +1810,34 @@ msgstr ""
 "faisait comme cela, vous éviterez de devoir éventuellement abandonner une "
 "fusion ayant échouée.\n"
 
-#: lib/merge.tcl:106
+#: lib/merge.tcl:107
 #, tcl-format
 msgid "%s of %s"
 msgstr "%s de %s"
 
-#: lib/merge.tcl:119
+#: lib/merge.tcl:120
 #, tcl-format
 msgid "Merging %s and %s..."
 msgstr "Fusion de %s et %s..."
 
-#: lib/merge.tcl:130
+#: lib/merge.tcl:131
 msgid "Merge completed successfully."
 msgstr "La fusion s'est faite avec succès."
 
-#: lib/merge.tcl:132
+#: lib/merge.tcl:133
 msgid "Merge failed.  Conflict resolution is required."
 msgstr "La fusion a echouée. Il est nécessaire de résoudre les conflicts."
 
-#: lib/merge.tcl:157
+#: lib/merge.tcl:158
 #, tcl-format
 msgid "Merge Into %s"
 msgstr "Fusion dans %s"
 
-#: lib/merge.tcl:176
+#: lib/merge.tcl:177
 msgid "Revision To Merge"
 msgstr "Révision à fusionner"
 
-#: lib/merge.tcl:211
+#: lib/merge.tcl:212
 msgid ""
 "Cannot abort while amending.\n"
 "\n"
@@ -1685,7 +1847,7 @@ msgstr ""
 "\n"
 "Vous devez finir de corriger ce commit.\n"
 
-#: lib/merge.tcl:221
+#: lib/merge.tcl:222
 msgid ""
 "Abort merge?\n"
 "\n"
@@ -1700,7 +1862,7 @@ msgstr ""
 "\n"
 "Abandonner quand même la fusion courante ?"
 
-#: lib/merge.tcl:227
+#: lib/merge.tcl:228
 msgid ""
 "Reset changes?\n"
 "\n"
@@ -1715,131 +1877,323 @@ msgstr ""
 "\n"
 "Réinitialiser quand même les modifications courantes ?"
 
-#: lib/merge.tcl:238
+#: lib/merge.tcl:239
 msgid "Aborting"
 msgstr "Abandon"
 
-#: lib/merge.tcl:238
+#: lib/merge.tcl:239
 msgid "files reset"
 msgstr "fichiers réinitialisés"
 
-#: lib/merge.tcl:266
+#: lib/merge.tcl:267
 msgid "Abort failed."
 msgstr "L'abandon a échoué."
 
-#: lib/merge.tcl:268
+#: lib/merge.tcl:269
 msgid "Abort completed.  Ready."
 msgstr "Abandon teminé. Prêt."
 
-#: lib/option.tcl:95
+#: lib/mergetool.tcl:8
+msgid "Force resolution to the base version?"
+msgstr "Forcer la résolution à la version de base ?"
+
+#: lib/mergetool.tcl:9
+msgid "Force resolution to this branch?"
+msgstr "Forcer la résolution à cette branche ?"
+
+#: lib/mergetool.tcl:10
+msgid "Force resolution to the other branch?"
+msgstr "Forcer la résolution à l'autre branche ?"
+
+#: lib/mergetool.tcl:14
+#, tcl-format
+msgid ""
+"Note that the diff shows only conflicting changes.\n"
+"\n"
+"%s will be overwritten.\n"
+"\n"
+"This operation can be undone only by restarting the merge."
+msgstr ""
+"Noter que le diff ne montre que les modifications en conflict.\n"
+"\n"
+"%s sera écrasé.\n"
+"\n"
+"Cette opération ne peut être défaite qu'en relançant la fusion."
+
+#: lib/mergetool.tcl:45
+#, tcl-format
+msgid "File %s seems to have unresolved conflicts, still stage?"
+msgstr "Le fichier %s semble avoir des conflicts non résolus, indéxer quand même ?"
+
+#: lib/mergetool.tcl:60
+#, tcl-format
+msgid "Adding resolution for %s"
+msgstr "Ajouter une résolution pour %s"
+
+#: lib/mergetool.tcl:141
+msgid "Cannot resolve deletion or link conflicts using a tool"
+msgstr "Impossible de résoudre la suppression ou de relier des conflicts en utilisant un outil"
+
+#: lib/mergetool.tcl:146
+msgid "Conflict file does not exist"
+msgstr "Le fichier en conflict n'existe pas."
+
+#: lib/mergetool.tcl:264
+#, tcl-format
+msgid "Not a GUI merge tool: '%s'"
+msgstr "'%s' n'est pas un outil graphique pour fusionner des fichiers."
+
+#: lib/mergetool.tcl:268
+#, tcl-format
+msgid "Unsupported merge tool '%s'"
+msgstr "Outil de fusion '%s' non supporté"
+
+#: lib/mergetool.tcl:303
+msgid "Merge tool is already running, terminate it?"
+msgstr "L'outil de fusion tourne déjà, faut-il le terminer ?"
+
+#: lib/mergetool.tcl:323
+#, tcl-format
+msgid ""
+"Error retrieving versions:\n"
+"%s"
+msgstr ""
+"Erreur lors de la récupération des versions:\n"
+"%s"
+
+#: lib/mergetool.tcl:343
+#, tcl-format
+msgid ""
+"Could not start the merge tool:\n"
+"\n"
+"%s"
+msgstr ""
+"Impossible de lancer l'outil de fusion:\n"
+"\n"
+"%s"
+
+#: lib/mergetool.tcl:347
+msgid "Running merge tool..."
+msgstr "Lancement de l'outil de fusion..."
+
+#: lib/mergetool.tcl:375 lib/mergetool.tcl:383
+msgid "Merge tool failed."
+msgstr "L'outil de fusion a échoué."
+
+#: lib/option.tcl:11
+#, tcl-format
+msgid "Invalid global encoding '%s'"
+msgstr "Encodage global invalide '%s'"
+
+#: lib/option.tcl:19
+#, tcl-format
+msgid "Invalid repo encoding '%s'"
+msgstr "Encodage de dépôt invalide '%s'"
+
+#: lib/option.tcl:117
 msgid "Restore Defaults"
 msgstr "Remettre les valeurs par défaut"
 
-#: lib/option.tcl:99
+#: lib/option.tcl:121
 msgid "Save"
 msgstr "Sauvegarder"
 
-#: lib/option.tcl:109
+#: lib/option.tcl:131
 #, tcl-format
 msgid "%s Repository"
 msgstr "Dépôt: %s"
 
-#: lib/option.tcl:110
+#: lib/option.tcl:132
 msgid "Global (All Repositories)"
 msgstr "Globales (tous les dépôts)"
 
-#: lib/option.tcl:116
+#: lib/option.tcl:138
 msgid "User Name"
 msgstr "Nom d'utilisateur"
 
-#: lib/option.tcl:117
+#: lib/option.tcl:139
 msgid "Email Address"
 msgstr "Adresse email"
 
-#: lib/option.tcl:119
+#: lib/option.tcl:141
 msgid "Summarize Merge Commits"
 msgstr "Résumer les commits de fusion"
 
-#: lib/option.tcl:120
+#: lib/option.tcl:142
 msgid "Merge Verbosity"
 msgstr "Fusion bavarde"
 
-#: lib/option.tcl:121
+#: lib/option.tcl:143
 msgid "Show Diffstat After Merge"
 msgstr "Montrer statistiques de diff après fusion"
 
-#: lib/option.tcl:123
+#: lib/option.tcl:144
+msgid "Use Merge Tool"
+msgstr "Utiliser outil de fusion"
+
+#: lib/option.tcl:146
 msgid "Trust File Modification Timestamps"
 msgstr "Faire confiance aux dates de modification de fichiers "
 
-#: lib/option.tcl:124
+#: lib/option.tcl:147
 msgid "Prune Tracking Branches During Fetch"
 msgstr "Purger les branches de suivi pendant la récupération"
 
-#: lib/option.tcl:125
+#: lib/option.tcl:148
 msgid "Match Tracking Branches"
 msgstr "Faire correspondre les branches de suivi"
 
-#: lib/option.tcl:126
+#: lib/option.tcl:149
 msgid "Blame Copy Only On Changed Files"
 msgstr "Annoter les copies seulement sur fichiers modifiés"
 
-#: lib/option.tcl:127
+#: lib/option.tcl:150
 msgid "Minimum Letters To Blame Copy On"
 msgstr "Minimum de caratères pour annoter une copie"
 
-#: lib/option.tcl:128
+#: lib/option.tcl:151
+msgid "Blame History Context Radius (days)"
+msgstr "Distance de blâme dans l'historique (jours)"
+
+#: lib/option.tcl:152
 msgid "Number of Diff Context Lines"
 msgstr "Nombre de lignes de contexte dans les diffs"
 
-#: lib/option.tcl:129
+#: lib/option.tcl:153
 msgid "Commit Message Text Width"
 msgstr "Largeur du texte de message de commit"
 
-#: lib/option.tcl:130
+#: lib/option.tcl:154
 msgid "New Branch Name Template"
 msgstr "Nouveau modèle de nom de branche"
 
-#: lib/option.tcl:194
+#: lib/option.tcl:155
+msgid "Default File Contents Encoding"
+msgstr "Encodage du contenu des fichiers par défaut"
+
+#: lib/option.tcl:203
+msgid "Change"
+msgstr "Modifier"
+
+#: lib/option.tcl:230
 msgid "Spelling Dictionary:"
 msgstr "Dictionnaire d'orthographe :"
 
-#: lib/option.tcl:218
+#: lib/option.tcl:254
 msgid "Change Font"
 msgstr "Modifier les polices"
 
-#: lib/option.tcl:222
+#: lib/option.tcl:258
 #, tcl-format
 msgid "Choose %s"
 msgstr "Choisir %s"
 
-#: lib/option.tcl:228
+#: lib/option.tcl:264
 msgid "pt."
 msgstr "pt."
 
-#: lib/option.tcl:242
+#: lib/option.tcl:278
 msgid "Preferences"
 msgstr "Préférences"
 
-#: lib/option.tcl:277
+#: lib/option.tcl:314
 msgid "Failed to completely save options:"
 msgstr "La sauvegarde complète des options a échouée :"
 
-#: lib/remote.tcl:165
+#: lib/remote.tcl:163
+msgid "Remove Remote"
+msgstr "Supprimer dépôt distant"
+
+#: lib/remote.tcl:168
 msgid "Prune from"
 msgstr "Purger de"
 
-#: lib/remote.tcl:170
+#: lib/remote.tcl:173
 msgid "Fetch from"
 msgstr "Récupérer de"
 
-#: lib/remote.tcl:213
+#: lib/remote.tcl:215
 msgid "Push to"
 msgstr "Pousser vers"
 
+#: lib/remote_add.tcl:19
+msgid "Add Remote"
+msgstr "Ajouter dépôt distant"
+
+#: lib/remote_add.tcl:24
+msgid "Add New Remote"
+msgstr "Ajouter nouveau dépôt distant"
+
+#: lib/remote_add.tcl:28 lib/tools_dlg.tcl:36
+msgid "Add"
+msgstr "Ajouter"
+
+#: lib/remote_add.tcl:37
+msgid "Remote Details"
+msgstr "Détails des dépôts distants"
+
+#: lib/remote_add.tcl:50
+msgid "Location:"
+msgstr "Emplacement:"
+
+#: lib/remote_add.tcl:62
+msgid "Further Action"
+msgstr "Action supplémentaire"
+
+#: lib/remote_add.tcl:65
+msgid "Fetch Immediately"
+msgstr "Récupérer immédiatement"
+
+#: lib/remote_add.tcl:71
+msgid "Initialize Remote Repository and Push"
+msgstr "Initialiser dépôt distant et pousser"
+
+#: lib/remote_add.tcl:77
+msgid "Do Nothing Else Now"
+msgstr "Ne rien faire d'autre maintenant"
+
+#: lib/remote_add.tcl:101
+msgid "Please supply a remote name."
+msgstr "Merci de fournir un nom de dépôt distant."
+
+#: lib/remote_add.tcl:114
+#, tcl-format
+msgid "'%s' is not an acceptable remote name."
+msgstr "'%s' n'est pas un nom de dépôt distant acceptable."
+
+#: lib/remote_add.tcl:125
+#, tcl-format
+msgid "Failed to add remote '%s' of location '%s'."
+msgstr "Échec de l'ajout du dépôt distant '%s' à l'emplacement '%s'."
+
+#: lib/remote_add.tcl:133 lib/transport.tcl:6
+#, tcl-format
+msgid "fetch %s"
+msgstr "récupérer %s"
+
+#: lib/remote_add.tcl:134
+#, tcl-format
+msgid "Fetching the %s"
+msgstr "Récupération de %s"
+
+#: lib/remote_add.tcl:157
+#, tcl-format
+msgid "Do not know how to initialize repository at location '%s'."
+msgstr "Pas de méthode connue pour initialiser le dépôt à l'emplacement '%s'."
+
+#: lib/remote_add.tcl:163 lib/transport.tcl:25 lib/transport.tcl:71
+#, tcl-format
+msgid "push %s"
+msgstr "pousser %s"
+
+#: lib/remote_add.tcl:164
+#, tcl-format
+msgid "Setting up the %s (at %s)"
+msgstr "Mise en place de %s (à %s)"
+
 #: lib/remote_branch_delete.tcl:29 lib/remote_branch_delete.tcl:34
-msgid "Delete Remote Branch"
-msgstr "Supprimer branche distante"
+msgid "Delete Branch Remotely"
+msgstr "Supprimer branche à distance"
 
 #: lib/remote_branch_delete.tcl:47
 msgid "From Repository"
@@ -1850,8 +2204,8 @@ msgid "Remote:"
 msgstr "Branche distante :"
 
 #: lib/remote_branch_delete.tcl:66 lib/transport.tcl:138
-msgid "Arbitrary URL:"
-msgstr "URL arbitraire :"
+msgid "Arbitrary Location:"
+msgstr "Emplacement arbitraire :"
 
 #: lib/remote_branch_delete.tcl:84
 msgid "Branches"
@@ -1921,6 +2275,22 @@ msgstr "Aucun dépôt n'est sélectionné."
 msgid "Scanning %s..."
 msgstr "Synchronisation de %s..."
 
+#: lib/search.tcl:21
+msgid "Find:"
+msgstr "Chercher :"
+
+#: lib/search.tcl:23
+msgid "Next"
+msgstr "Suivant"
+
+#: lib/search.tcl:24
+msgid "Prev"
+msgstr "Précédant"
+
+#: lib/search.tcl:25
+msgid "Case-Sensitive"
+msgstr "Sensible à la casse"
+
 #: lib/shortcut.tcl:20 lib/shortcut.tcl:61
 msgid "Cannot write shortcut:"
 msgstr "Impossible d'écrire le raccourcis :"
@@ -1958,23 +2328,188 @@ msgstr "Vérificateur d'orthographe non reconnu"
 msgid "No Suggestions"
 msgstr "Aucune suggestion"
 
-#: lib/spellcheck.tcl:387
+#: lib/spellcheck.tcl:388
 msgid "Unexpected EOF from spell checker"
 msgstr "EOF inattendue envoyée par le vérificateur d'orthographe"
 
-#: lib/spellcheck.tcl:391
+#: lib/spellcheck.tcl:392
 msgid "Spell Checker Failed"
 msgstr "Le vérificateur d'orthographe a échoué"
 
+#: lib/sshkey.tcl:31
+msgid "No keys found."
+msgstr "Aucune clé trouvée."
+
+#: lib/sshkey.tcl:34
+#, tcl-format
+msgid "Found a public key in: %s"
+msgstr "Clé publique trouvée dans : %s"
+
+#: lib/sshkey.tcl:40
+msgid "Generate Key"
+msgstr "Générer une clé"
+
+#: lib/sshkey.tcl:56
+msgid "Copy To Clipboard"
+msgstr "Copier dans le presse papier"
+
+#: lib/sshkey.tcl:70
+msgid "Your OpenSSH Public Key"
+msgstr "Votre clé publique Open SSH"
+
+#: lib/sshkey.tcl:78
+msgid "Generating..."
+msgstr "Génération..."
+
+#: lib/sshkey.tcl:84
+#, tcl-format
+msgid ""
+"Could not start ssh-keygen:\n"
+"\n"
+"%s"
+msgstr ""
+"Impossible de lancer ssh-keygen:\n"
+"\n"
+"%s"
+
+#: lib/sshkey.tcl:111
+msgid "Generation failed."
+msgstr "La génération a échoué."
+
+#: lib/sshkey.tcl:118
+msgid "Generation succeded, but no keys found."
+msgstr "La génération a réussi, mais aucune clé n'a été trouvée."
+
+#: lib/sshkey.tcl:121
+#, tcl-format
+msgid "Your key is in: %s"
+msgstr "Votre clé est dans : %s"
+
 #: lib/status_bar.tcl:83
 #, tcl-format
 msgid "%s ... %*i of %*i %s (%3i%%)"
 msgstr "%s ... %*i de %*i %s (%3i%%)"
 
-#: lib/transport.tcl:6
+#: lib/tools.tcl:75
 #, tcl-format
-msgid "fetch %s"
-msgstr "récupérer %s"
+msgid "Running %s requires a selected file."
+msgstr "Lancer %s nécessite qu'un fichier soit sélectionné."
+
+#: lib/tools.tcl:90
+#, tcl-format
+msgid "Are you sure you want to run %s?"
+msgstr "Êtes vous sûr de vouloir lancer %s ?"
+
+#: lib/tools.tcl:110
+#, tcl-format
+msgid "Tool: %s"
+msgstr "Outil : %s"
+
+#: lib/tools.tcl:111
+#, tcl-format
+msgid "Running: %s"
+msgstr "Lancement de : %s"
+
+#: lib/tools.tcl:149
+#, tcl-format
+msgid "Tool completed succesfully: %s"
+msgstr "L'outil a terminé avec succès : %s"
+
+#: lib/tools.tcl:151
+#, tcl-format
+msgid "Tool failed: %s"
+msgstr "L'outil a échoué : %s"
+
+#: lib/tools_dlg.tcl:22
+msgid "Add Tool"
+msgstr "Ajouter outil"
+
+#: lib/tools_dlg.tcl:28
+msgid "Add New Tool Command"
+msgstr "Ajouter nouvelle commande d'outil"
+
+#: lib/tools_dlg.tcl:33
+msgid "Add globally"
+msgstr "Ajouter globalement"
+
+#: lib/tools_dlg.tcl:45
+msgid "Tool Details"
+msgstr "Détails sur l'outil"
+
+#: lib/tools_dlg.tcl:48
+msgid "Use '/' separators to create a submenu tree:"
+msgstr "Utiliser les séparateurs '/' pour créer un arbre de sous menus :"
+
+#: lib/tools_dlg.tcl:61
+msgid "Command:"
+msgstr "Commande :"
+
+#: lib/tools_dlg.tcl:74
+msgid "Show a dialog before running"
+msgstr "Montrer une boîte de dialogue avant le lancement"
+
+#: lib/tools_dlg.tcl:80
+msgid "Ask the user to select a revision (sets $REVISION)"
+msgstr "Demander à l'utilisateur de sélectionner une révision (change $REVISION)"
+
+#: lib/tools_dlg.tcl:85
+msgid "Ask the user for additional arguments (sets $ARGS)"
+msgstr "Demander à l'utilisateur des arguments supplémentaires (change $ARGS)"
+
+#: lib/tools_dlg.tcl:92
+msgid "Don't show the command output window"
+msgstr "Ne pas montrer la fenêtre de sortie des commandes"
+
+#: lib/tools_dlg.tcl:97
+msgid "Run only if a diff is selected ($FILENAME not empty)"
+msgstr "Lancer seulement si un diff est selectionné ($FILENAME non vide)"
+
+#: lib/tools_dlg.tcl:121
+msgid "Please supply a name for the tool."
+msgstr "Merci de fournir un nom pour l'outil."
+
+#: lib/tools_dlg.tcl:129
+#, tcl-format
+msgid "Tool '%s' already exists."
+msgstr "L'outil '%s' existe déjà."
+
+#: lib/tools_dlg.tcl:151
+#, tcl-format
+msgid ""
+"Could not add tool:\n"
+"%s"
+msgstr ""
+"Impossible d'ajouter l'outil:\n"
+"%s"
+
+#: lib/tools_dlg.tcl:190
+msgid "Remove Tool"
+msgstr "Supprimer l'outil"
+
+#: lib/tools_dlg.tcl:196
+msgid "Remove Tool Commands"
+msgstr "Supprimer des commandes d'outil"
+
+#: lib/tools_dlg.tcl:200
+msgid "Remove"
+msgstr "Supprimer"
+
+#: lib/tools_dlg.tcl:236
+msgid "(Blue denotes repository-local tools)"
+msgstr "(Le bleu indique des outils locaux au dépôt)"
+
+#: lib/tools_dlg.tcl:297
+#, tcl-format
+msgid "Run Command: %s"
+msgstr "Lancer commande : %s"
+
+#: lib/tools_dlg.tcl:311
+msgid "Arguments"
+msgstr "Arguments"
+
+#: lib/tools_dlg.tcl:348
+msgid "OK"
+msgstr "OK"
 
 #: lib/transport.tcl:7
 #, tcl-format
@@ -1991,11 +2526,6 @@ msgstr "purger à distance %s"
 msgid "Pruning tracking branches deleted from %s"
 msgstr "Nettoyer les branches de suivi supprimées de %s"
 
-#: lib/transport.tcl:25 lib/transport.tcl:71
-#, tcl-format
-msgid "push %s"
-msgstr "pousser %s"
-
 #: lib/transport.tcl:26
 #, tcl-format
 msgid "Pushing changes to %s"
-- 
1.5.6.1.2293.gb0a4

^ permalink raw reply related

* Re: Git.pm
From: nadim khemir @ 2008-11-23 19:58 UTC (permalink / raw)
  To: git
In-Reply-To: <20081120083446.GF10544@machine.or.cz>

On Thursday 20 November 2008 09.34.46 you wrote:
>   I know it's quite some time since you wrote this mail originally -
> have you read the Lea's thread I have recommended? What is your current
> plan?

>   I think the current rough consensus in the Git community is to go with
> Lea's design and implementation after extending it with a nice way to
> run arbitrary Git commands. This is also desirable since then we can use
> her patches to make gitweb use Git.pm.

Hi,

Yes I read Lea's thread. My current plan is to:
	- not rush
	- analyse where the different modules are used and how (and document it)
	- understand the process of working with the git team
	- tell my fellow perl developers about this (done, so far very good response)
	- confer with the people having git related modules (a few)
	- gather ideas for what nededs to be changed (not much this far)
	- put a development strategy in place
	- understand the test mechanisms you've been using so far
	- pray hard to any helping deity and get real

Cheers, Nadim.

^ permalink raw reply

* Re: Git.pm
From: nadim khemir @ 2008-11-23 20:09 UTC (permalink / raw)
  To: git
In-Reply-To: <m363mhlw92.fsf@localhost.localdomain>

On Friday 21 November 2008 03.56.51 Jakub Narebski wrote:
> Actually there are one and a half of Perl interfaces to Git: Git.pm
> created by Pasky (who, as far as I understand is not a Perl hacker)
> which is in git.git repository, and Git::Repo and friends created by
> Lea Wiemann during her work on "gitweb caching" project at Google
> Summer of Code 2008 (you can find her repository at git wiki page
> http://git.or.cz/gitwiki/SoC2008Projects).
>
>
> If I remember history of Git.pm correctly, it was first created as a
> way to collect together and uniquify various versions of safe_pipe and
> safe_qx which were used by various Perl scripts in git; something like
> Perl version of git-sh-setup.sh for shell scripts... At first it even
> used XS in parts, but the build system was deemed too unportable (it
> depended on -fPIC). One of design decisions was to use Error.pm for
> throwing errors; I'm not a Perl hacker, so I cannot say if this was a
> good decision, and if implementation of this part is good.

Using Error.pm is not a bad decision even if more simple mechanisms do the 
job.

> Lea Wiemann work on Git::Repo and friends was created as object
> oriented interface. It was build from ground up instead of reusing
> Git.pm to be not encumbered by Git.pm cruft... unfortunately it means
> also abandoning all the work that went in Git.pm to make it portable
> (read: make it work with crippled ActiveState Perl). You can find
> discussion on the design of Git::Repo and decision of it being clean
> state implementation at link given by Pasky.
>
> P.S. I have "[RFC] Git Perl bindings, and OO interface" half-written
> (well, more like a third), a bit stalled. I'll try to find time to
> finish it and send it to git mailing list.

That would be very usefull. the  relevant information should be integrated in 
the module itself.

Thank you for your input on the history of Git.pm.

Cheers, Nadim

^ permalink raw reply

* Re: [PATCH] git-gui: french translation update
From: Shawn O. Pearce @ 2008-11-23 20:54 UTC (permalink / raw)
  To: Christian Couder; +Cc: git
In-Reply-To: <20081123205220.8469422f.chriscool@tuxfamily.org>

Christian Couder <chriscool@tuxfamily.org> wrote:
> 
> Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
> ---
>  git-gui/po/fr.po | 1124 +++++++++++++++++++++++++++++++++++++++--------------
>  1 files changed, 827 insertions(+), 297 deletions(-)
> 
> 	As usual, I hope there will be no encoding problems.

Applied clean.  Thanks.
 
-- 
Shawn.

^ permalink raw reply

* [RFC/PATCH] bisect: teach "skip" to accept special arguments like "A..B"
From: Christian Couder @ 2008-11-23 21:02 UTC (permalink / raw)
  To: Junio C Hamano, Johannes Schindelin; +Cc: git, H. Peter Anvin

The current "git bisect skip" syntax is "git bisect skip [<rev>...]"
so it's already possible to skip a range of revisions using
something like:

$ git bisect skip $(git rev-list A..B)

where A and B are the bounds of the range we want to skip.

This patch teaches "git bisect skip" to accept:

$ git bisect skip A..B

as an abbreviation for the former command.

This is done by checking each argument to see if it contains two
dots one after the other ('..'), and by expending it using
"git rev-list" if that is the case.

Note that this patch will not make "git bisect skip" accept all
that "git rev-list" accepts, as things like "^A B" for exemple
will not work. But things like "A B..C D E F.. ..G H...I" should
work as expected.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
 git-bisect.sh |   19 ++++++++++++++++++-
 1 files changed, 18 insertions(+), 1 deletions(-)

	Dscho wrote:
	> Would it not be more intuitive to have support for
	>
        > git bisect skip A..B
	>
	> ?

	Here is a patch to do that. I am not sure it's worth it
	because this is a special case in many ways.

diff --git a/git-bisect.sh b/git-bisect.sh
index 0d0e278..6706bc1 100755
--- a/git-bisect.sh
+++ b/git-bisect.sh
@@ -191,6 +191,21 @@ check_expected_revs() {
 	done
 }
 
+bisect_skip() {
+        all=''
+	for arg in "$@"
+	do
+	    case "$arg" in
+            *..*)
+                revs=$(git rev-list "$arg") || die "Bad rev input: $arg" ;;
+            *)
+                revs="'$arg'" ;;
+	    esac
+            all="$all $revs"
+        done
+        bisect_state 'skip' $all
+}
+
 bisect_state() {
 	bisect_autostart
 	state=$1
@@ -630,8 +645,10 @@ case "$#" in
         git bisect -h ;;
     start)
         bisect_start "$@" ;;
-    bad|good|skip)
+    bad|good)
         bisect_state "$cmd" "$@" ;;
+    skip)
+        bisect_skip "$@" ;;
     next)
         # Not sure we want "next" at the UI level anymore.
         bisect_next "$@" ;;
-- 
1.6.0.4.768.g22eb.dirty

^ permalink raw reply related

* Re: Stgit and refresh-temp
From: Catalin Marinas @ 2008-11-23 21:20 UTC (permalink / raw)
  To: Karl Hasselström; +Cc: Jon Smirl, Git Mailing List
In-Reply-To: <20081112101439.GA27469@diana.vm.bytemark.co.uk>

2008/11/12 Karl Hasselström <kha@treskal.com>:
> On 2008-11-12 10:02:10 +0000, Catalin Marinas wrote:
>
>> I think it's just a matter of updating HEAD on the "merge_conflict"
>> path but I'm still not fully confident in modifying the new lib
>> infrastructure.
>
> You're probably right.

The simple patch below seems to fix it the goto issue. Could you
please confirm its correctness (the patch might be wrapped by the web
interface)?

diff --git a/stgit/lib/transaction.py b/stgit/lib/transaction.py
index 6623645..0f414d8 100644
--- a/stgit/lib/transaction.py
+++ b/stgit/lib/transaction.py
@@ -321,6 +321,7 @@ class StackTransaction(object):
         if any(getattr(cd, a) != getattr(orig_cd, a) for a in
                ['parent', 'tree', 'author', 'message']):
             comm = self.__stack.repository.commit(cd)
+            self.head = comm
         else:
             comm = None
             s = ' (unmodified)'

Thanks.

-- 
Catalin

^ permalink raw reply related

* [PATCH] Display (empty) when appropriate for the goto command
From: Catalin Marinas @ 2008-11-23 21:23 UTC (permalink / raw)
  To: Karl Hasselström; +Cc: git

This is a fix for bug #11810. The original implementation of goto used
to display (empty patch) when a patch became empty during a push + merge
operation. This patch adds this feature again.

Signed-off-by: Catalin Marinas <catalin.marinas@gmail.com>
---
 stgit/lib/transaction.py |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/stgit/lib/transaction.py b/stgit/lib/transaction.py
index de62a8c..6623645 100644
--- a/stgit/lib/transaction.py
+++ b/stgit/lib/transaction.py
@@ -290,7 +290,6 @@ class StackTransaction(object):
         conflicts to them."""
         orig_cd = self.patches[pn].data
         cd = orig_cd.set_committer(None)
-        s = ['', ' (empty)'][cd.is_nochange()]
         oldparent = cd.parent
         cd = cd.set_parent(self.top)
         base = oldparent.data.tree
@@ -298,6 +297,7 @@ class StackTransaction(object):
         theirs = cd.tree
         tree, self.temp_index_tree = self.temp_index.merge(
             base, ours, theirs, self.temp_index_tree)
+        s = ''
         merge_conflict = False
         if not tree:
             if iw == None:
@@ -324,6 +324,8 @@ class StackTransaction(object):
         else:
             comm = None
             s = ' (unmodified)'
+        if not merge_conflict and cd.is_nochange():
+            s = ' (empty)'
         out.info('Pushed %s%s' % (pn, s))
         def update():
             if comm:

^ permalink raw reply related

* Re: [RFC/PATCH] bisect: teach "skip" to accept special arguments like "A..B"
From: Johannes Schindelin @ 2008-11-24  0:28 UTC (permalink / raw)
  To: Christian Couder; +Cc: Junio C Hamano, git, H. Peter Anvin
In-Reply-To: <20081123220249.2e7f30a5.chriscool@tuxfamily.org>

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1370 bytes --]

Hi,

On Sun, 23 Nov 2008, Christian Couder wrote:

> The current "git bisect skip" syntax is "git bisect skip [<rev>...]"
> so it's already possible to skip a range of revisions using
> something like:
> 
> $ git bisect skip $(git rev-list A..B)
> 
> where A and B are the bounds of the range we want to skip.
> 
> This patch teaches "git bisect skip" to accept:
> 
> $ git bisect skip A..B
> 
> as an abbreviation for the former command.
> 
> This is done by checking each argument to see if it contains two
> dots one after the other ('..'), and by expending it using
> "git rev-list" if that is the case.

s/expend/expand/

> Note that this patch will not make "git bisect skip" accept all
> that "git rev-list" accepts, as things like "^A B" for exemple
> will not work. But things like "A B..C D E F.. ..G H...I" should
> work as expected.
> 
> Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
> ---
>  git-bisect.sh |   19 ++++++++++++++++++-
>  1 files changed, 18 insertions(+), 1 deletions(-)
> 
> 	Dscho wrote:
> 	> Would it not be more intuitive to have support for
> 	>
>         > git bisect skip A..B
> 	>
> 	> ?
> 
> 	Here is a patch to do that. I am not sure it's worth it
> 	because this is a special case in many ways.

Why not have something like

	skip)
		for arg in $(git rev-list "$@")
		do
			bisect_state skip $arg
		done

?

Ciao,
Dscho

^ permalink raw reply

* Re: [BUGFIX PATCH 2/2] fast-export: use an unsorted string list for extra_refs
From: Junio C Hamano @ 2008-11-24  1:07 UTC (permalink / raw)
  To: Miklos Vajna; +Cc: Johannes Schindelin, git, gitster
In-Reply-To: <20081123180353.GM4746@genesis.frugalware.org>

Thanks both; I do not have time to actually double-check and apply for the
next 36 hours or so, though.

^ permalink raw reply

* [RFC PATCH 0/4] Teach git fetch to verify signed tags automatically
From: Deskin Miller @ 2008-11-24  3:23 UTC (permalink / raw)
  To: git; +Cc: Deskin Miller

It struck me a while back when I fetched a new tagged release from git.git that
if I wanted to verify the tag's signature, I'd have to issue another command to
do so.  Shouldn't git be able to do that for me automatically, when it fetches
signed tags?  Now it does.  Also, 'git remote update' gets this for free.

Individual commit messages explain things reasonably well, I hope; here are a
few points for discussion:

-Is refactoring builtin-verify-tag.c the right thing to do?
-Now that the SIGPIPE ignoring is occurring at a lower level, should it be
 removed from cmd_verify_tag?
-Output format: good, bad, ugly?
-What to do if a tag is found to have a bad signature?

Deskin Miller (4):
  Refactor builtin-verify-tag.c
  verify-tag.c: ignore SIGPIPE around gpg invocation
  verify-tag.c: suppress gpg output if asked
  Make git fetch verify signed tags

 Makefile             |    2 +
 builtin-fetch.c      |   25 +++++++++++----
 builtin-verify-tag.c |   61 ++----------------------------------
 t/t7004-tag.sh       |   37 ++++++++++++++++++++++
 verify-tag.c         |   84 ++++++++++++++++++++++++++++++++++++++++++++++++++
 verify-tag.h         |   10 ++++++
 6 files changed, 155 insertions(+), 64 deletions(-)
 create mode 100644 verify-tag.c
 create mode 100644 verify-tag.h

^ permalink raw reply

* [RFC PATCH 1/4] Refactor builtin-verify-tag.c
From: Deskin Miller @ 2008-11-24  3:23 UTC (permalink / raw)
  To: git; +Cc: Deskin Miller
In-Reply-To: <1227497000-8684-1-git-send-email-deskinm@umich.edu>

builtin-verify-tag.c didn't expose any of its functionality to be used
internally.  Refactor some of it into new verify-tag.c and expose
verify_tag_sha1 able to be called from elsewhere in git.

Signed-off-by: Deskin Miller <deskinm@umich.edu>
---
 Makefile             |    2 +
 builtin-verify-tag.c |   61 ++-------------------------------------
 verify-tag.c         |   77 ++++++++++++++++++++++++++++++++++++++++++++++++++
 verify-tag.h         |   10 ++++++
 4 files changed, 93 insertions(+), 57 deletions(-)
 create mode 100644 verify-tag.c
 create mode 100644 verify-tag.h

diff --git a/Makefile b/Makefile
index 35adafa..b372aa4 100644
--- a/Makefile
+++ b/Makefile
@@ -392,6 +392,7 @@ LIB_H += tree-walk.h
 LIB_H += unpack-trees.h
 LIB_H += userdiff.h
 LIB_H += utf8.h
+LIB_H += verify-tag.h
 LIB_H += wt-status.h
 
 LIB_OBJS += abspath.o
@@ -490,6 +491,7 @@ LIB_OBJS += unpack-trees.o
 LIB_OBJS += userdiff.o
 LIB_OBJS += usage.o
 LIB_OBJS += utf8.o
+LIB_OBJS += verify-tag.o
 LIB_OBJS += walker.o
 LIB_OBJS += wrapper.o
 LIB_OBJS += write_or_die.o
diff --git a/builtin-verify-tag.c b/builtin-verify-tag.c
index 729a159..dd350e8 100644
--- a/builtin-verify-tag.c
+++ b/builtin-verify-tag.c
@@ -7,65 +7,16 @@
  */
 #include "cache.h"
 #include "builtin.h"
-#include "tag.h"
-#include "run-command.h"
+#include "verify-tag.h"
 #include <signal.h>
 
 static const char builtin_verify_tag_usage[] =
 		"git verify-tag [-v|--verbose] <tag>...";
 
-#define PGP_SIGNATURE "-----BEGIN PGP SIGNATURE-----"
-
-static int run_gpg_verify(const char *buf, unsigned long size, int verbose)
-{
-	struct child_process gpg;
-	const char *args_gpg[] = {"gpg", "--verify", "FILE", "-", NULL};
-	char path[PATH_MAX], *eol;
-	size_t len;
-	int fd, ret;
-
-	fd = git_mkstemp(path, PATH_MAX, ".git_vtag_tmpXXXXXX");
-	if (fd < 0)
-		return error("could not create temporary file '%s': %s",
-						path, strerror(errno));
-	if (write_in_full(fd, buf, size) < 0)
-		return error("failed writing temporary file '%s': %s",
-						path, strerror(errno));
-	close(fd);
-
-	/* find the length without signature */
-	len = 0;
-	while (len < size && prefixcmp(buf + len, PGP_SIGNATURE)) {
-		eol = memchr(buf + len, '\n', size - len);
-		len += eol ? eol - (buf + len) + 1 : size - len;
-	}
-	if (verbose)
-		write_in_full(1, buf, len);
-
-	memset(&gpg, 0, sizeof(gpg));
-	gpg.argv = args_gpg;
-	gpg.in = -1;
-	args_gpg[2] = path;
-	if (start_command(&gpg)) {
-		unlink(path);
-		return error("could not run gpg.");
-	}
-
-	write_in_full(gpg.in, buf, len);
-	close(gpg.in);
-	ret = finish_command(&gpg);
-
-	unlink(path);
-
-	return ret;
-}
-
 static int verify_tag(const char *name, int verbose)
 {
 	enum object_type type;
 	unsigned char sha1[20];
-	char *buf;
-	unsigned long size;
 	int ret;
 
 	if (get_sha1(name, sha1))
@@ -76,13 +27,9 @@ static int verify_tag(const char *name, int verbose)
 		return error("%s: cannot verify a non-tag object of type %s.",
 				name, typename(type));
 
-	buf = read_sha1_file(sha1, &type, &size);
-	if (!buf)
-		return error("%s: unable to read file.", name);
-
-	ret = run_gpg_verify(buf, size, verbose);
-
-	free(buf);
+	ret = verify_tag_sha1(sha1, verbose);
+	if (ret)
+		error("Failed to verify %s.", name);
 	return ret;
 }
 
diff --git a/verify-tag.c b/verify-tag.c
new file mode 100644
index 0000000..c9be331
--- /dev/null
+++ b/verify-tag.c
@@ -0,0 +1,77 @@
+/*
+ * Internals for "git verify-tag"
+ *
+ * Copyright (c) 2008 Deskin Miller <deskinm@umich.edu>
+ *
+ */
+#include "cache.h"
+#include "object.h"
+#include "run-command.h"
+
+#define PGP_SIGNATURE "-----BEGIN PGP SIGNATURE-----"
+
+static int run_gpg_verify(const char *buf, unsigned long size, int verbose)
+{
+	struct child_process gpg;
+	const char *args_gpg[] = {"gpg", "--verify", "FILE", "-", NULL};
+	char path[PATH_MAX], *eol;
+	size_t len;
+	int fd, ret;
+
+	fd = git_mkstemp(path, PATH_MAX, ".git_vtag_tmpXXXXXX");
+	if (fd < 0)
+		return error("could not create temporary file '%s': %s",
+						path, strerror(errno));
+	if (write_in_full(fd, buf, size) < 0)
+		return error("failed writing temporary file '%s': %s",
+						path, strerror(errno));
+	close(fd);
+
+	/* find the length without signature */
+	len = 0;
+	while (len < size && prefixcmp(buf + len, PGP_SIGNATURE)) {
+		eol = memchr(buf + len, '\n', size - len);
+		len += eol ? eol - (buf + len) + 1 : size - len;
+	}
+	if (verbose)
+		write_in_full(1, buf, len);
+
+	memset(&gpg, 0, sizeof(gpg));
+	gpg.argv = args_gpg;
+	gpg.in = -1;
+	args_gpg[2] = path;
+	if (start_command(&gpg)) {
+		unlink(path);
+		return error("could not run gpg.");
+	}
+
+	write_in_full(gpg.in, buf, len);
+	close(gpg.in);
+	ret = finish_command(&gpg);
+
+	unlink(path);
+
+	return ret;
+}
+
+int verify_tag_sha1(const unsigned char *sha1, int verbose)
+{
+	enum object_type type;
+	char *buf;
+	unsigned long size;
+	int ret;
+
+	type = sha1_object_info(sha1, NULL);
+	if (type != OBJ_TAG)
+		return error("Cannot verify a non-tag object of type %s.",
+				typename(type));
+
+	buf = read_sha1_file(sha1, &type, &size);
+	if (!buf)
+		return error("Cnable to read file.");
+
+	ret = run_gpg_verify(buf, size, verbose);
+
+	free(buf);
+	return ret;
+}
diff --git a/verify-tag.h b/verify-tag.h
new file mode 100644
index 0000000..45bdca7
--- /dev/null
+++ b/verify-tag.h
@@ -0,0 +1,10 @@
+#ifndef VERIFY_TAG_H
+#define VERIFY_TAG_H
+/*
+ * Internals for "git verify-tag"
+ *
+ * Copyright (c) 2008 Deskin Miller <deskinm@umich.edu>
+ */
+extern int verify_tag_sha1(const unsigned char *sha1, int verbose);
+
+#endif /* VERIFY_TAG_H */
-- 
1.6.0.4.770.ga8394

^ permalink raw reply related

* [RFC PATCH 2/4] verify-tag.c: ignore SIGPIPE around gpg invocation
From: Deskin Miller @ 2008-11-24  3:23 UTC (permalink / raw)
  To: git; +Cc: Deskin Miller
In-Reply-To: <1227497000-8684-2-git-send-email-deskinm@umich.edu>

builtin-verify-tag.c already sets SIG_IGN for SIGPIPE before calling
verify_tag, but new callers of verify_tag_sha1 may not have modified the
signal handler, and shouldn't have to.  Save and restore the signal
handler for SIGPIPE around the invocation of gpg.

Signed-off-by: Deskin Miller <deskinm@umich.edu>
---
 verify-tag.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/verify-tag.c b/verify-tag.c
index c9be331..c3e35f3 100644
--- a/verify-tag.c
+++ b/verify-tag.c
@@ -7,6 +7,7 @@
 #include "cache.h"
 #include "object.h"
 #include "run-command.h"
+#include <signal.h>
 
 #define PGP_SIGNATURE "-----BEGIN PGP SIGNATURE-----"
 
@@ -17,6 +18,7 @@ static int run_gpg_verify(const char *buf, unsigned long size, int verbose)
 	char path[PATH_MAX], *eol;
 	size_t len;
 	int fd, ret;
+	sighandler_t save_handle;
 
 	fd = git_mkstemp(path, PATH_MAX, ".git_vtag_tmpXXXXXX");
 	if (fd < 0)
@@ -40,8 +42,10 @@ static int run_gpg_verify(const char *buf, unsigned long size, int verbose)
 	gpg.argv = args_gpg;
 	gpg.in = -1;
 	args_gpg[2] = path;
+	save_handle = signal(SIGPIPE, SIG_IGN);
 	if (start_command(&gpg)) {
 		unlink(path);
+		signal(SIGPIPE, save_handle);
 		return error("could not run gpg.");
 	}
 
@@ -50,6 +54,7 @@ static int run_gpg_verify(const char *buf, unsigned long size, int verbose)
 	ret = finish_command(&gpg);
 
 	unlink(path);
+	signal(SIGPIPE, save_handle);
 
 	return ret;
 }
-- 
1.6.0.4.770.ga8394

^ permalink raw reply related

* [RFC PATCH 3/4] verify-tag.c: suppress gpg output if asked
From: Deskin Miller @ 2008-11-24  3:23 UTC (permalink / raw)
  To: git; +Cc: Deskin Miller
In-Reply-To: <1227497000-8684-3-git-send-email-deskinm@umich.edu>

Previously, tag verification would output messages from gpg on standard
error.  Allow this to be controlled by a parameter to verify_tag_sha1.

Signed-off-by: Deskin Miller <deskinm@umich.edu>
---
 verify-tag.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/verify-tag.c b/verify-tag.c
index c3e35f3..b47acc9 100644
--- a/verify-tag.c
+++ b/verify-tag.c
@@ -35,13 +35,15 @@ static int run_gpg_verify(const char *buf, unsigned long size, int verbose)
 		eol = memchr(buf + len, '\n', size - len);
 		len += eol ? eol - (buf + len) + 1 : size - len;
 	}
-	if (verbose)
+	if (verbose == 1)
 		write_in_full(1, buf, len);
 
 	memset(&gpg, 0, sizeof(gpg));
 	gpg.argv = args_gpg;
 	gpg.in = -1;
 	args_gpg[2] = path;
+	if (verbose == -1)
+		gpg.no_stderr = 1;
 	save_handle = signal(SIGPIPE, SIG_IGN);
 	if (start_command(&gpg)) {
 		unlink(path);
-- 
1.6.0.4.770.ga8394

^ permalink raw reply related

* [RFC PATCH 4/4] Make git fetch verify signed tags
From: Deskin Miller @ 2008-11-24  3:23 UTC (permalink / raw)
  To: git; +Cc: Deskin Miller
In-Reply-To: <1227497000-8684-4-git-send-email-deskinm@umich.edu>

When git fetch downloads signed tag objects, make it verify them right
then.  This extends the output summary of fetch to include "(good
signature)" for valid tags and "(BAD SIGNATURE)" for invalid tags.  If
the user does not have the correct key in the gpg keyring, gpg returns
2, verify_tag_sha1 returns -2 and nothing additional is output about
the tag's validity.

Alternate fetch method 'git remote update' gets this check as well due
to the use of the fetch routines.

Signed-off-by: Deskin Miller <deskinm@umich.edu>
---
 builtin-fetch.c |   25 ++++++++++++++++++-------
 t/t7004-tag.sh  |   37 +++++++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+), 7 deletions(-)

diff --git a/builtin-fetch.c b/builtin-fetch.c
index f151cfa..f7a50b7 100644
--- a/builtin-fetch.c
+++ b/builtin-fetch.c
@@ -10,6 +10,7 @@
 #include "transport.h"
 #include "run-command.h"
 #include "parse-options.h"
+#include "verify-tag.h"
 
 static const char * const builtin_fetch_usage[] = {
 	"git fetch [options] [<repository> <refspec>...]",
@@ -233,11 +234,16 @@ static int update_local_ref(struct ref *ref,
 
 	if (!is_null_sha1(ref->old_sha1) &&
 	    !prefixcmp(ref->name, "refs/tags/")) {
-		int r;
+		int r, v;
 		r = s_update_ref("updating tag", ref, 0);
-		sprintf(display, "%c %-*s %-*s -> %s%s", r ? '!' : '-',
+		if (type == OBJ_TAG)
+			v = verify_tag_sha1(ref->new_sha1, -1);
+		sprintf(display, "%c %-*s %-*s -> %s%s", r ? '!' :
+			(type == OBJ_TAG ? (v == -1 ? '!' : '-') : '-'),
 			SUMMARY_WIDTH, "[tag update]", REFCOL_WIDTH, remote,
-			pretty_ref, r ? "  (unable to update local ref)" : "");
+			pretty_ref, r ? "  (unable to update local ref)" :
+			(type == OBJ_TAG ? (v == 0 ? " (good signature)" :
+			(v == -1 ? " (BAD SIGNATURE)" : "")) : ""));
 		return r;
 	}
 
@@ -246,7 +252,7 @@ static int update_local_ref(struct ref *ref,
 	if (!current || !updated) {
 		const char *msg;
 		const char *what;
-		int r;
+		int r, v;
 		if (!strncmp(ref->name, "refs/tags/", 10)) {
 			msg = "storing tag";
 			what = "[new tag]";
@@ -257,9 +263,14 @@ static int update_local_ref(struct ref *ref,
 		}
 
 		r = s_update_ref(msg, ref, 0);
-		sprintf(display, "%c %-*s %-*s -> %s%s", r ? '!' : '*',
-			SUMMARY_WIDTH, what, REFCOL_WIDTH, remote, pretty_ref,
-			r ? "  (unable to update local ref)" : "");
+		if (type == OBJ_TAG)
+			v = verify_tag_sha1(ref->new_sha1, -1);
+		sprintf(display, "%c %-*s %-*s -> %s%s", r ? '!' :
+			(type == OBJ_TAG ? (v == -1 ? '!' : '*') : '*'),
+			SUMMARY_WIDTH, what, REFCOL_WIDTH, remote,
+			pretty_ref, r ? "  (unable to update local ref)" :
+			(type == OBJ_TAG ? (v == 0 ? " (good signature)" :
+			(v == -1 ? " (BAD SIGNATURE)" : "")) : ""));
 		return r;
 	}
 
diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh
index f377fea..00327cc 100755
--- a/t/t7004-tag.sh
+++ b/t/t7004-tag.sh
@@ -1037,6 +1037,43 @@ test_expect_success \
 	'test_must_fail git tag -s -m tail tag-gpg-failure'
 git config --unset user.signingkey
 
+git tag -s -m 'good tag' good-tag HEAD
+bad=$(git cat-file tag good-tag | sed -e 's/good-tag/bad-tag/' | git mktag)
+git tag bad-tag $bad
+head=$(git rev-parse HEAD)
+nonkey=$(cat <<EOF | git mktag
+object $head
+type commit
+tag v1.6.0.4
+tagger Junio C Hamano <gitster@pobox.com> 1226208581 -0800
+
+GIT 1.6.0.4
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.4.9 (GNU/Linux)
+
+iEYEABECAAYFAkkWdUUACgkQwMbZpPMRm5rSmwCfWu+K/hXyLUnEWoOMYy1eKuMK
+KcoAnjB2qir794ibWPy6cn11uUbk7AlC
+=eaFZ
+-----END PGP SIGNATURE-----
+EOF
+)
+git tag nonkey-tag $nonkey
+
+echo 'bad-tag (BAD SIGNATURE)' > expect
+echo 'good-tag (good signature)' >> expect
+echo 'nonkey-tag' >> expect
+
+test_expect_success \
+	'git fetch verifies tags' \
+	'mkdir clone &&
+	(cd clone &&
+	git init &&
+	git remote add origin file://"$(cd .. && pwd)" &&
+	git fetch origin 2>../actual) &&
+	sed -i -ne "/ \(bad\|good\|nonkey\)-tag/s/^.*->[^a-z]*//p" actual &&
+	test_cmp expect actual
+	'
+
 # try to verify without gpg:
 
 rm -rf gpghome
-- 
1.6.0.4.770.ga8394

^ permalink raw reply related

* Re: [PATCH 1/4] builtin-clone: fix a memory leak in cmd_clone()
From: Junio C Hamano @ 2008-11-24  3:51 UTC (permalink / raw)
  To: Miklos Vajna; +Cc: git
In-Reply-To: <6bd31bceb3840f14d747972b4858e1c5b215744d.1227227976.git.vmiklos@frugalware.org>

Miklos Vajna <vmiklos@frugalware.org> writes:

> Signed-off-by: Miklos Vajna <vmiklos@frugalware.org>
> ---
>  builtin-clone.c |    1 +
>  1 files changed, 1 insertions(+), 0 deletions(-)
>
> diff --git a/builtin-clone.c b/builtin-clone.c
> index 8e1a1d3..da21cab 100644
> --- a/builtin-clone.c
> +++ b/builtin-clone.c
> @@ -516,6 +516,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
>  		refs = transport_get_remote_refs(transport);
>  		transport_fetch_refs(transport, refs);
>  	}
> +	free(dir);
>  
>  	clear_extra_refs();

Can't this be done much earlier?  This variable can potentially be
assigned to work_tree, but after we set up the atexit handler neither dir
nor work_tree are not used (it is a bit hard to see as this function
itself is a bit too big to be maintainable).

^ permalink raw reply

* Re: [RFC PATCH 0/4] Teach git fetch to verify signed tags automatically
From: Junio C Hamano @ 2008-11-24  4:53 UTC (permalink / raw)
  To: Deskin Miller; +Cc: git
In-Reply-To: <1227497000-8684-1-git-send-email-deskinm@umich.edu>

Deskin Miller <deskinm@umich.edu> writes:

> It struck me a while back when I fetched a new tagged release from git.git that
> if I wanted to verify the tag's signature, I'd have to issue another command to
> do so.  Shouldn't git be able to do that for me automatically, when it fetches
> signed tags?  Now it does.  Also, 'git remote update' gets this for free.

I think this should be done inside your own hook.  Not interested at all
in a solution to touch builtin-fetch.c, unless if the patch is about
adding a new hook so that people with other needs can use it as well.

^ permalink raw reply

* Re: [RFC PATCH 0/4] Teach git fetch to verify signed tags automatically
From: Junio C Hamano @ 2008-11-24  5:30 UTC (permalink / raw)
  To: Deskin Miller; +Cc: git
In-Reply-To: <7v4p1xohbw.fsf@gitster.siamese.dyndns.org>

Junio C Hamano <gitster@pobox.com> writes:

> Deskin Miller <deskinm@umich.edu> writes:
>
>> It struck me a while back when I fetched a new tagged release from git.git that
>> if I wanted to verify the tag's signature, I'd have to issue another command to
>> do so.  Shouldn't git be able to do that for me automatically, when it fetches
>> signed tags?  Now it does.  Also, 'git remote update' gets this for free.
>
> I think this should be done inside your own hook.  Not interested at all
> in a solution to touch builtin-fetch.c, unless if the patch is about
> adding a new hook so that people with other needs can use it as well.

... or a much stronger case can be made why this shouldn't be done in a
hook.

I realize "not interested at all" was a bit too strong, so I am trying to
rephrase it here.  The cycle that begins with an RFC that leads to
discussion and review is about clarifying the rationale and design
incrementally, so please do not get offended by my no, and sorry for using
unnecessarily strong wording.

What I meant was more like "The justification as given in the message does
not interest me in the patch at all as it stands.  I do not understand why
this has to be done as a patch to git-fetch itself, not in a hook script,
or why doing it inside git-fetch is a better approach than doing it in a
hook (if there already is a hook mechanism to do this)".

^ permalink raw reply

* [PATCH] git checkout: don't warn about unborn branch if -f is already passed
From: Matt McCutchen @ 2008-11-24  6:55 UTC (permalink / raw)
  To: git

I think it's unnecessary to warn that the checkout has been forced due to an
unborn current branch if -f has been explicitly passed.  For one project, I am
using git-new-workdir to create workdirs from a bare repository whose HEAD is
set to an unborn branch, and this warning started to irritate me.

Signed-off-by: Matt McCutchen <matt@mattmccutchen.net>
---
 builtin-checkout.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/builtin-checkout.c b/builtin-checkout.c
index 464fd25..7f3bd7b 100644
--- a/builtin-checkout.c
+++ b/builtin-checkout.c
@@ -553,7 +553,7 @@ static int switch_branches(struct checkout_opts *opts, struct branch_info *new)
 	if (!opts->quiet && !old.path && old.commit && new->commit != old.commit)
 		describe_detached_head("Previous HEAD position was", old.commit);
 
-	if (!old.commit) {
+	if (!old.commit && !opts->force) {
 		if (!opts->quiet) {
 			fprintf(stderr, "warning: You appear to be on a branch yet to be born.\n");
 			fprintf(stderr, "warning: Forcing checkout of %s.\n", new->name);
-- 
1.6.0.2.593.g91df

^ 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