hgbook
changeset 543:51b5d56744c5
Merge Spanish version
author | Bryan O'Sullivan <bos@serpentine.com> |
---|---|
date | Thu Jan 29 22:00:07 2009 -0800 (2009-01-29) |
parents | 73b094b764ec b35930ce7a70 |
children | f5ab40759789 547d3aa25ef0 |
files | en/examples/bisect |
line diff
1.1 --- a/en/99defs.tex Thu Jan 15 10:13:51 2009 +0100 1.2 +++ b/en/99defs.tex Thu Jan 29 22:00:07 2009 -0800 1.3 @@ -136,6 +136,10 @@ 1.4 % Reference entry for a command option with only long form. 1.5 \newcommand{\loptref}[2]{\subsubsection{\hgopt{#1}{--#2} option}} 1.6 1.7 +% command to generate a footnote to be used as a translator's note 1.8 +\newcommand{\ndt}[1]{\footnote{\textbf{N. del T.} #1}} 1.9 + 1.10 + 1.11 %%% Local Variables: 1.12 %%% mode: latex 1.13 %%% TeX-master: "00book"
2.1 --- a/en/collab.tex Thu Jan 15 10:13:51 2009 +0100 2.2 +++ b/en/collab.tex Thu Jan 29 22:00:07 2009 -0800 2.3 @@ -461,7 +461,7 @@ 2.4 take a look at your system documentation to figure out how to install 2.5 it. 2.6 2.7 -On Windows, you'll first need to choose download a suitable ssh 2.8 +On Windows, you'll first need to download a suitable ssh 2.9 client. There are two alternatives. 2.10 \begin{itemize} 2.11 \item Simon Tatham's excellent PuTTY package~\cite{web:putty} provides 2.12 @@ -495,7 +495,7 @@ 2.13 2.14 When you generate a key pair, it's usually \emph{highly} advisable to 2.15 protect it with a passphrase. (The only time that you might not want 2.16 -to do this id when you're using the ssh protocol for automated tasks 2.17 +to do this is when you're using the ssh protocol for automated tasks 2.18 on a secure network.) 2.19 2.20 Simply generating a key pair isn't enough, however. You'll need to 2.21 @@ -737,7 +737,7 @@ 2.22 named something like \dirname{public\_html} in their home directory, 2.23 from which they can serve up web pages. A file named \filename{foo} 2.24 in this directory will be accessible at a URL of the form 2.25 -\texttt{http://www.example.com/\~username/foo}. 2.26 +\texttt{http://www.example.com/\~{}username/foo}. 2.27 2.28 To get started, find the \sfilename{hgweb.cgi} script that should be 2.29 present in your Mercurial installation. If you can't quickly find a
3.1 --- a/en/concepts.tex Thu Jan 15 10:13:51 2009 +0100 3.2 +++ b/en/concepts.tex Thu Jan 29 22:00:07 2009 -0800 3.3 @@ -309,7 +309,7 @@ 3.4 changesets to see which one introduced a bug. In cases like this, the 3.5 natural thing to do is update the working directory to the changeset 3.6 you're interested in, and then examine the files in the working 3.7 -directory directly to see their contents as they werea when you 3.8 +directory directly to see their contents as they were when you 3.9 committed that changeset. The effect of this is shown in 3.10 figure~\ref{fig:concepts:wdir-pre-branch}. 3.11
4.1 --- a/en/examples/bisect Thu Jan 15 10:13:51 2009 +0100 4.2 +++ b/en/examples/bisect Thu Jan 29 22:00:07 2009 -0800 4.3 @@ -1,7 +1,11 @@ 4.4 #!/bin/bash 4.5 4.6 +if hg -v | head -1 | grep -e "version 0.*" 4.7 +then 4.8 +#On mercurial 1.0 and later bisect is a builtin 4.9 echo '[extensions]' >> $HGRC 4.10 echo 'hbisect =' >> $HGRC 4.11 +fi 4.12 4.13 # XXX There's some kind of horrible nondeterminism in the execution of 4.14 # bisect at the moment. Ugh.
5.1 --- a/en/examples/bisect.commits.out Thu Jan 15 10:13:51 2009 +0100 5.2 +++ b/en/examples/bisect.commits.out Thu Jan 29 22:00:07 2009 -0800 5.3 @@ -8,38 +8,3 @@ 5.4 5.5 5.6 5.7 - 5.8 - 5.9 - 5.10 - 5.11 - 5.12 - 5.13 - 5.14 - 5.15 - 5.16 - 5.17 - 5.18 - 5.19 - 5.20 - 5.21 - 5.22 - 5.23 - 5.24 - 5.25 - 5.26 - 5.27 - 5.28 - 5.29 - 5.30 - 5.31 - 5.32 - 5.33 - 5.34 - 5.35 - 5.36 - 5.37 - 5.38 - 5.39 - 5.40 - 5.41 -
6.1 --- a/en/examples/bisect.help.out Thu Jan 15 10:13:51 2009 +0100 6.2 +++ b/en/examples/bisect.help.out Thu Jan 29 22:00:07 2009 -0800 6.3 @@ -19,3 +19,5 @@ 6.4 6.5 6.6 6.7 + 6.8 +
7.1 --- a/en/examples/bisect.init.out Thu Jan 15 10:13:51 2009 +0100 7.2 +++ b/en/examples/bisect.init.out Thu Jan 29 22:00:07 2009 -0800 7.3 @@ -1,3 +1,2 @@ 7.4 7.5 7.6 -
8.1 --- a/en/examples/bisect.search.bad-init.out Thu Jan 15 10:13:51 2009 +0100 8.2 +++ b/en/examples/bisect.search.bad-init.out Thu Jan 29 22:00:07 2009 -0800 8.3 @@ -1,22 +1,1 @@ 8.4 8.5 - 8.6 - 8.7 - 8.8 - 8.9 - 8.10 - 8.11 - 8.12 - 8.13 - 8.14 - 8.15 - 8.16 - 8.17 - 8.18 - 8.19 - 8.20 - 8.21 - 8.22 - 8.23 - 8.24 - 8.25 -
9.1 --- a/en/examples/bisect.search.good-init.out Thu Jan 15 10:13:51 2009 +0100 9.2 +++ b/en/examples/bisect.search.good-init.out Thu Jan 29 22:00:07 2009 -0800 9.3 @@ -1,22 +1,3 @@ 9.4 9.5 9.6 9.7 - 9.8 - 9.9 - 9.10 - 9.11 - 9.12 - 9.13 - 9.14 - 9.15 - 9.16 - 9.17 - 9.18 - 9.19 - 9.20 - 9.21 - 9.22 - 9.23 - 9.24 - 9.25 -
10.1 --- a/en/examples/bisect.search.init.out Thu Jan 15 10:13:51 2009 +0100 10.2 +++ b/en/examples/bisect.search.init.out Thu Jan 29 22:00:07 2009 -0800 10.3 @@ -3,20 +3,3 @@ 10.4 10.5 10.6 10.7 - 10.8 - 10.9 - 10.10 - 10.11 - 10.12 - 10.13 - 10.14 - 10.15 - 10.16 - 10.17 - 10.18 - 10.19 - 10.20 - 10.21 - 10.22 - 10.23 -
11.1 --- a/en/examples/bisect.search.reset.out Thu Jan 15 10:13:51 2009 +0100 11.2 +++ b/en/examples/bisect.search.reset.out Thu Jan 29 22:00:07 2009 -0800 11.3 @@ -1,22 +1,1 @@ 11.4 11.5 - 11.6 - 11.7 - 11.8 - 11.9 - 11.10 - 11.11 - 11.12 - 11.13 - 11.14 - 11.15 - 11.16 - 11.17 - 11.18 - 11.19 - 11.20 - 11.21 - 11.22 - 11.23 - 11.24 - 11.25 -
12.1 --- a/en/examples/bisect.search.rest.out Thu Jan 15 10:13:51 2009 +0100 12.2 +++ b/en/examples/bisect.search.rest.out Thu Jan 29 22:00:07 2009 -0800 12.3 @@ -14,56 +14,3 @@ 12.4 12.5 12.6 12.7 - 12.8 - 12.9 - 12.10 - 12.11 - 12.12 - 12.13 - 12.14 - 12.15 - 12.16 - 12.17 - 12.18 - 12.19 - 12.20 - 12.21 - 12.22 - 12.23 - 12.24 - 12.25 - 12.26 - 12.27 - 12.28 - 12.29 - 12.30 - 12.31 - 12.32 - 12.33 - 12.34 - 12.35 - 12.36 - 12.37 - 12.38 - 12.39 - 12.40 - 12.41 - 12.42 - 12.43 - 12.44 - 12.45 - 12.46 - 12.47 - 12.48 - 12.49 - 12.50 - 12.51 - 12.52 - 12.53 - 12.54 - 12.55 - 12.56 - 12.57 - 12.58 - 12.59 -
13.1 --- a/en/examples/bisect.search.step1.out Thu Jan 15 10:13:51 2009 +0100 13.2 +++ b/en/examples/bisect.search.step1.out Thu Jan 29 22:00:07 2009 -0800 13.3 @@ -9,22 +9,3 @@ 13.4 13.5 13.6 13.7 - 13.8 - 13.9 - 13.10 - 13.11 - 13.12 - 13.13 - 13.14 - 13.15 - 13.16 - 13.17 - 13.18 - 13.19 - 13.20 - 13.21 - 13.22 - 13.23 - 13.24 - 13.25 -
14.1 --- a/en/examples/bisect.search.step2.out Thu Jan 15 10:13:51 2009 +0100 14.2 +++ b/en/examples/bisect.search.step2.out Thu Jan 29 22:00:07 2009 -0800 14.3 @@ -2,22 +2,3 @@ 14.4 14.5 14.6 14.7 - 14.8 - 14.9 - 14.10 - 14.11 - 14.12 - 14.13 - 14.14 - 14.15 - 14.16 - 14.17 - 14.18 - 14.19 - 14.20 - 14.21 - 14.22 - 14.23 - 14.24 - 14.25 -
15.1 --- a/en/examples/branch-repo.bugfix.out Thu Jan 15 10:13:51 2009 +0100 15.2 +++ b/en/examples/branch-repo.bugfix.out Thu Jan 29 22:00:07 2009 -0800 15.3 @@ -5,7 +5,7 @@ 15.4 $ \textbf{echo 'I fixed a bug using only echo!' >> myfile} 15.5 $ \textbf{hg commit -m 'Important fix for 1.0.1'} 15.6 $ \textbf{hg push} 15.7 -pushing to /tmp/branch-repo4rF-PL/myproject-1.0.1 15.8 +pushing to 15.9 searching for changes 15.10 adding changesets 15.11 adding manifests
16.1 --- a/en/examples/branching.stable.out Thu Jan 15 10:13:51 2009 +0100 16.2 +++ b/en/examples/branching.stable.out Thu Jan 29 22:00:07 2009 -0800 16.3 @@ -5,7 +5,7 @@ 16.4 $ \textbf{echo 'This is a fix to a boring feature.' > myfile} 16.5 $ \textbf{hg commit -m 'Fix a bug'} 16.6 $ \textbf{hg push} 16.7 -pushing to /tmp/branchingfJgZac/stable 16.8 +pushing to 16.9 searching for changes 16.10 adding changesets 16.11 adding manifests
17.1 --- a/en/examples/daily.copy.merge.out Thu Jan 15 10:13:51 2009 +0100 17.2 +++ b/en/examples/daily.copy.merge.out Thu Jan 29 22:00:07 2009 -0800 17.3 @@ -7,7 +7,7 @@ 17.4 added 1 changesets with 1 changes to 1 files (+1 heads) 17.5 (run 'hg heads' to see heads, 'hg merge' to merge) 17.6 $ \textbf{hg merge} 17.7 -merging file and new-file to new-file 17.8 +merging file and new-file 17.9 0 files updated, 1 files merged, 0 files removed, 0 files unresolved 17.10 (branch merge, don't forget to commit) 17.11 $ \textbf{cat new-file}
18.1 --- a/en/examples/tour-merge-conflict.commit.out Thu Jan 15 10:13:51 2009 +0100 18.2 +++ b/en/examples/tour-merge-conflict.commit.out Thu Jan 29 22:00:07 2009 -0800 18.3 @@ -4,6 +4,29 @@ 18.4 > \textbf{Nigerian dictator Sani Abacha.} 18.5 > \textbf{EOF} 18.6 $ \textbf{hg resolve -m letter.txt} 18.7 +hg: unknown command 'resolve' 18.8 +Mercurial Distributed SCM 18.9 + 18.10 +basic commands: 18.11 + 18.12 + add add the specified files on the next commit 18.13 + annotate show changeset information per file line 18.14 + clone make a copy of an existing repository 18.15 + commit commit the specified files or all outstanding changes 18.16 + diff diff repository (or selected files) 18.17 + export dump the header and diffs for one or more changesets 18.18 + init create a new repository in the given directory 18.19 + log show revision history of entire repository or files 18.20 + merge merge working directory with another revision 18.21 + parents show the parents of the working dir or revision 18.22 + pull pull changes from the specified source 18.23 + push push changes to the specified destination 18.24 + remove remove the specified files on the next commit 18.25 + serve export the repository via HTTP 18.26 + status show changed files in the working directory 18.27 + update update working directory 18.28 + 18.29 +use "hg help" for the full list of commands or "hg -v" for details 18.30 $ \textbf{hg commit -m 'Send me your money'} 18.31 $ \textbf{hg tip} 18.32 changeset:
19.1 --- a/en/examples/tour-merge-conflict.merge.out Thu Jan 15 10:13:51 2009 +0100 19.2 +++ b/en/examples/tour-merge-conflict.merge.out Thu Jan 29 22:00:07 2009 -0800 19.3 @@ -4,7 +4,9 @@ 19.4 merge: warning: conflicts during merge 19.5 merging letter.txt failed! 19.6 0 files updated, 0 files merged, 0 files removed, 1 files unresolved 19.7 -use 'hg resolve' to retry unresolved file merges 19.8 +There are unresolved merges, you can redo the full merge using: 19.9 + hg update -C 1 19.10 + hg merge 2 19.11 $ \textbf{cat letter.txt} 19.12 Greetings! 19.13
20.1 --- a/en/examples/tour.help.out Thu Jan 15 10:13:51 2009 +0100 20.2 +++ b/en/examples/tour.help.out Thu Jan 29 22:00:07 2009 -0800 20.3 @@ -3,7 +3,7 @@ 20.4 20.5 create a new repository in the given directory 20.6 20.7 - Initialize a new repository in the given directory. If the given 20.8 + Initialize a new repository in the given directory. If the given 20.9 directory does not exist, it is created. 20.10 20.11 If no directory is given, the current directory is used.
21.1 --- a/en/examples/tour.ls.out Thu Jan 15 10:13:51 2009 +0100 21.2 +++ b/en/examples/tour.ls.out Thu Jan 29 22:00:07 2009 -0800 21.3 @@ -1,5 +1,5 @@ 21.4 $ \textbf{ls -l} 21.5 -total 4 21.6 + 21.7 21.8 $ \textbf{ls hello} 21.9 Makefile hello.c
22.1 --- a/en/examples/tour.version.out Thu Jan 15 10:13:51 2009 +0100 22.2 +++ b/en/examples/tour.version.out Thu Jan 29 22:00:07 2009 -0800 22.3 @@ -1,5 +1,5 @@ 22.4 $ \textbf{hg version} 22.5 -Mercurial Distributed SCM (version ) 22.6 +Mercurial Distributed SCM (version 1.0) 22.7 22.8 Copyright (C) 2005-2008 Matt Mackall <mpm@selenic.com> and others 22.9 This is free software; see the source for copying conditions. There is NO
23.1 --- a/en/hook.tex Thu Jan 15 10:13:51 2009 +0100 23.2 +++ b/en/hook.tex Thu Jan 29 22:00:07 2009 -0800 23.3 @@ -509,7 +509,7 @@ 23.4 whitespace from a file. This is concise and useful enough that I will 23.5 reproduce it here. 23.6 \begin{codesample2} 23.7 - perl -pi -e 's,\\s+\$,,' filename 23.8 + perl -pi -e 's,\textbackslash{}s+\$,,' filename 23.9 \end{codesample2} 23.10 23.11 \section{Bundled hooks}
24.1 --- a/en/mq-collab.tex Thu Jan 15 10:13:51 2009 +0100 24.2 +++ b/en/mq-collab.tex Thu Jan 29 22:00:07 2009 -0800 24.3 @@ -275,7 +275,7 @@ 24.4 backports a piece of code to~2.6.9 will have a~\texttt{2.6.9} guard. 24.5 \end{itemize} 24.6 This variety of guards gives me considerable flexibility in 24.7 -qdetermining what kind of source tree I want to end up with. For most 24.8 +determining what kind of source tree I want to end up with. For most 24.9 situations, the selection of appropriate guards is automated during 24.10 the build process, but I can manually tune the guards to use for less 24.11 common circumstances.
25.1 --- a/en/mq.tex Thu Jan 15 10:13:51 2009 +0100 25.2 +++ b/en/mq.tex Thu Jan 29 22:00:07 2009 -0800 25.3 @@ -525,7 +525,7 @@ 25.4 modifies \filename{foo} with six hunks, and one of them fails to 25.5 apply, you will have: an unmodified \filename{foo.orig}, a 25.6 \filename{foo.rej} containing one hunk, and \filename{foo}, containing 25.7 -the changes made by the five successful five hunks. 25.8 +the changes made by the five successful hunks. 25.9 25.10 \subsection{Some quirks of patch representation} 25.11
26.1 --- a/en/template.tex Thu Jan 15 10:13:51 2009 +0100 26.2 +++ b/en/template.tex Thu Jan 29 22:00:07 2009 -0800 26.3 @@ -244,7 +244,7 @@ 26.4 date using the same format used in email headers. Yields a string 26.5 like ``\Verb+Mon, 04 Sep 2006 15:13:13 -0700+''. 26.6 \item[\tplkwfilt{node}{short}] Changeset hash. Yield the short form 26.7 - of a changeset hash, i.e.~a 12-byte hexadecimal string. 26.8 + of a changeset hash, i.e.~a 12-character hexadecimal string. 26.9 \item[\tplkwfilt{date}{shortdate}] \tplkword{date} keyword. Render 26.10 the year, month, and day of the date. Yields a string like 26.11 ``\Verb+2006-09-04+''. 26.12 @@ -452,7 +452,7 @@ 26.13 \item Subversion's output includes a count in the header of the number 26.14 of lines in the commit message. We cannot replicate this in 26.15 Mercurial; the templating engine does not currently provide a filter 26.16 - that counts the number of items it is passed. 26.17 + that counts the number of lines the template generates. 26.18 \end{itemize} 26.19 It took me no more than a minute or two of work to replace literal 26.20 text from an example of Subversion's output with some keywords and
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 27.2 +++ b/es/00book.tex Thu Jan 29 22:00:07 2009 -0800 27.3 @@ -0,0 +1,81 @@ 27.4 +% The use of oneside here is a temporary hack; \marginpar entries 27.5 +% don't show up on odd pages of PDF output without it. Sigh. 27.6 +\documentclass[oneside]{book} 27.7 +\usepackage[spanish]{babel} 27.8 +\usepackage{enumerate} 27.9 +\usepackage{fullpage} 27.10 +\usepackage{makeidx} 27.11 +\usepackage{ifpdf} 27.12 +\usepackage{graphicx} 27.13 +\usepackage{pslatex} 27.14 +\usepackage{fancyvrb} 27.15 +\usepackage[utf8]{inputenc} %accents in spanish 27.16 +% leave hyperref until last 27.17 +\ifpdf 27.18 +\usepackage[colorlinks=true,bookmarks=true,pdftitle={Distributed 27.19 + revision control with Mercurial},pdfsubject={Revision 27.20 + control},pdfkeywords={Mercurial, Revision control, Distributed 27.21 + revision control},pdfauthor={Bryan O'Sullivan}]{hyperref} 27.22 +\fi 27.23 + 27.24 +\include{99defs} 27.25 + 27.26 +\title{Control Distribuido de Revisiones con Mercurial} \author{Bryan 27.27 + O'Sullivan} 27.28 +\date{Copyright \copyright\ 2006, 2007 Bryan O'Sullivan.\\ 27.29 + Este material puede distribuirse únicamente bajo los términos y 27.30 + condiciones establecidos en la versión 1.0 de la Licencia de Publicación 27.31 + Abierta (OPL). Refiérase por favor al apéndice~\ref{cha:opl} para encontrar el 27.32 + texto de la licencia.\\ 27.33 + Este libro fue preparado a partir de 27.34 + \href{http://mercurial.intuxication.org/hg/mercurial_book_es}{rev~\input{build_id}} 27.35 + usando Mercurial \href{http://www.selenic.com/hg/}{rev~\input{hg_id}}.} 27.36 + 27.37 +\makeindex 27.38 + 27.39 +\begin{document} 27.40 +\spanishdeactivate{<>"~} 27.41 +\maketitle 27.42 + 27.43 +\addcontentsline{toc}{chapter}{Índice general} 27.44 +\pagenumbering{roman} 27.45 +\tableofcontents 27.46 +\listoffigures 27.47 +%\listoftables 27.48 + 27.49 +\pagenumbering{arabic} 27.50 + 27.51 +\include{preface} 27.52 +\include{intro} 27.53 +\include{tour-basic} 27.54 +\include{tour-merge} 27.55 +\include{concepts} 27.56 +\include{daily} 27.57 +\include{collab} 27.58 +\include{filenames} 27.59 +\include{branch} 27.60 +\include{undo} 27.61 +\include{hook} 27.62 +\include{template} 27.63 +\include{mq} 27.64 +\include{mq-collab} 27.65 +\include{hgext} 27.66 + 27.67 +\appendix 27.68 +\include{cmdref} 27.69 +\include{mq-ref} 27.70 +\include{srcinstall} 27.71 +\include{license} 27.72 +\addcontentsline{toc}{chapter}{Bibliografía} 27.73 +\bibliographystyle{alpha} 27.74 +\bibliography{99book} 27.75 + 27.76 +\addcontentsline{toc}{chapter}{Índice alfabético} 27.77 +\printindex 27.78 + 27.79 +\end{document} 27.80 + 27.81 +%%% Local Variables: 27.82 +%%% mode: latex 27.83 +%%% TeX-master: t 27.84 +%%% End:
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 28.2 +++ b/es/99book.bib Thu Jan 29 22:00:07 2009 -0800 28.3 @@ -0,0 +1,1 @@ 28.4 +../en/99book.bib 28.5 \ No newline at end of file
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 29.2 +++ b/es/99defs.tex Thu Jan 29 22:00:07 2009 -0800 29.3 @@ -0,0 +1,146 @@ 29.4 +% Bug ID. 29.5 +\newcommand{\bug}[1]{\index{Base de datos de fallos de Mercurial 29.6 + !\href{http://www.selenic.com/mercurial/bts/issue#1}{fallo 29.7 + ~#1}}\href{http://www.selenic.com/mercurial/bts/issue#1}{Fallo de 29.8 + Mercurial No.~#1}} 29.9 + 29.10 +% File name in the user's home directory. 29.11 +\newcommand{\tildefile}[1]{\texttt{\~{}/#1}} 29.12 + 29.13 +% File name. 29.14 +\newcommand{\filename}[1]{\texttt{#1}} 29.15 + 29.16 +% Directory name. 29.17 +\newcommand{\dirname}[1]{\texttt{#1}} 29.18 + 29.19 +% File name, with index entry. 29.20 +% The ``s'' prefix comes from ``special''. 29.21 +\newcommand{\sfilename}[1]{\index{\texttt{#1}, fichero}\texttt{#1}} 29.22 + 29.23 +% Directory name, with index entry. 29.24 +\newcommand{\sdirname}[1]{\index{\texttt{#1}, directorio}\texttt{#1}} 29.25 + 29.26 +% Mercurial extension. 29.27 +\newcommand{\hgext}[1]{\index{\texttt{#1}, extensi\'on}\texttt{#1}} 29.28 + 29.29 +% Command provided by a Mercurial extension. 29.30 +\newcommand{\hgxcmd}[2]{\index{\texttt{#2}, comando (extensi\'on 29.31 +\texttt{#1})}\index{\texttt{#1}, extensi\'on!comando \texttt{#2}}``\texttt{hg #2}''} 29.32 + 29.33 +% Mercurial command. 29.34 +\newcommand{\hgcmd}[1]{\index{\texttt{#1}, comando}``\texttt{hg #1}''} 29.35 + 29.36 +% Mercurial command, with arguments. 29.37 +\newcommand{\hgcmdargs}[2]{\index{\texttt{#1}, comando}``\texttt{hg #1 #2}''} 29.38 + 29.39 +\newcommand{\tplkword}[1]{\index{\texttt{#1}, palabra clave de 29.40 +plantilla}\index{palabras clave de plantilla!\texttt{#1}}\texttt{#1}} 29.41 + 29.42 +\newcommand{\tplkwfilt}[2]{\index{\texttt{#1}, palabra clave de plantilla!filtro 29.43 +\texttt{#2}}\index{filtros de plantilla!\texttt{#2}}\index{\texttt{#2}, filtro 29.44 +de plantilla}\texttt{#2}} 29.45 + 29.46 +\newcommand{\tplfilter}[1]{\index{filtros de 29.47 +plantilla!\texttt{#1}}\index{\texttt{#1}, filtro de plantilla}\texttt{#1}} 29.48 + 29.49 +% Shell/system command. 29.50 +\newcommand{\command}[1]{\index{\texttt{#1}, comando de sistema}\texttt{#1}} 29.51 + 29.52 +% Shell/system command, with arguments. 29.53 +\newcommand{\cmdargs}[2]{\index{\texttt{#1} comando de sistema}``\texttt{#1 #2}''} 29.54 + 29.55 +% Mercurial command option. 29.56 +\newcommand{\hgopt}[2]{\index{\texttt{#1}, comando!opción \texttt{#2}}\texttt{#2}} 29.57 + 29.58 +% Mercurial command option, provided by an extension command. 29.59 +\newcommand{\hgxopt}[3]{\index{\texttt{#2}, comando (extensión 29.60 +\texttt{#1})!opción \texttt{#3}}\index{\texttt{#1}, extensión!comando 29.61 +\texttt{#2}!opción\texttt{#3}}\texttt{#3}} 29.62 + 29.63 +% Mercurial global option. 29.64 +\newcommand{\hggopt}[1]{\index{opciones globales!opción \texttt{#1}}\texttt{#1}} 29.65 + 29.66 +% Shell/system command option. 29.67 +\newcommand{\cmdopt}[2]{\index{\texttt{#1}, comando!opción \texttt{#2}}\texttt{#2}} 29.68 + 29.69 +% Command option. 29.70 +\newcommand{\option}[1]{\texttt{#1}} 29.71 + 29.72 +% Software package. 29.73 +\newcommand{\package}[1]{\index{\texttt{#1}, paquete}\texttt{#1}} 29.74 + 29.75 +% Section name from a hgrc file. 29.76 +\newcommand{\rcsection}[1]{\index{\texttt{hgrc}, fichero!sección \texttt{#1}}\texttt{[#1]}} 29.77 + 29.78 +% Named item in a hgrc file section. 29.79 +\newcommand{\rcitem}[2]{\index{\texttt{hgrc}, fichero!sección 29.80 +\texttt{#1}!entrada \texttt{#2}}\texttt{#2}} 29.81 + 29.82 +% hgrc file. 29.83 +\newcommand{\hgrc}{\index{fichero de configuración!\texttt{hgrc} 29.84 + (Linux/Unix)}\index{\texttt{hgrc}, fichero de configuración}\texttt{hgrc}} 29.85 + 29.86 +% Mercurial.ini file. 29.87 +\newcommand{\hgini}{\index{fichero de configuración!\texttt{Mercurial.ini} 29.88 + (Windows)}\index{\texttt{Mercurial.ini}, fichero de configuración}\texttt{Mercurial.ini}} 29.89 + 29.90 +% Hook name. 29.91 +\newcommand{\hook}[1]{\index{\texttt{#1}, gancho}\index{ganchos!\texttt{#1}}\texttt{#1}} 29.92 + 29.93 +% Environment variable. 29.94 +\newcommand{\envar}[1]{\index{\texttt{#1}, variable de entorno}\index{variables 29.95 +de entorno!\texttt{#1}}\texttt{#1}} 29.96 + 29.97 +% Python module. 29.98 +\newcommand{\pymod}[1]{\index{\texttt{#1}, módulo}\texttt{#1}} 29.99 + 29.100 +% Python class in a module. 29.101 +\newcommand{\pymodclass}[2]{\index{\texttt{#1}, módulo!clase \texttt{#2}}\texttt{#1.#2}} 29.102 + 29.103 +% Python function in a module. 29.104 +\newcommand{\pymodfunc}[2]{\index{\texttt{#1}, módulo!función \texttt{#2}}\texttt{#1.#2}} 29.105 + 29.106 +% Note: blah blah. 29.107 +\newsavebox{\notebox} 29.108 +\newenvironment{note}% 29.109 + {\begin{lrbox}{\notebox}\begin{minipage}{0.7\textwidth}\textbf{Nota:}\space}% 29.110 + {\end{minipage}\end{lrbox}\fbox{\usebox{\notebox}}} 29.111 +\newenvironment{caution}% 29.112 + {\begin{lrbox}{\notebox}\begin{minipage}{0.7\textwidth}\textbf{Precaución:}\space}% 29.113 + {\end{minipage}\end{lrbox}\fbox{\usebox{\notebox}}} 29.114 + 29.115 +% Code sample, eating 4 characters of leading space. 29.116 +\DefineVerbatimEnvironment{codesample4}{Verbatim}{frame=single,gobble=4,numbers=left,commandchars=\\\{\}} 29.117 + 29.118 +% Code sample, eating 2 characters of leading space. 29.119 +\DefineVerbatimEnvironment{codesample2}{Verbatim}{frame=single,gobble=2,numbers=left,commandchars=\\\{\}} 29.120 + 29.121 +% Interaction from the examples directory. 29.122 +\newcommand{\interaction}[1]{\VerbatimInput[frame=single,numbers=left,commandchars=\\\{\}]{examples/#1.lxo}} 29.123 +% Example code from the examples directory. 29.124 +\newcommand{\excode}[1]{\VerbatimInput[frame=single,numbers=left,commandchars=\\\{\}]{../examples/#1}} 29.125 + 29.126 +% Graphics inclusion. 29.127 +\ifpdf 29.128 + \newcommand{\grafix}[2][]{\includegraphics[#1]{#2}} 29.129 +\else 29.130 + \newcommand{\grafix}[1]{\includegraphics{#1.png}} 29.131 +\fi 29.132 + 29.133 +% Reference entry for a command. 29.134 +\newcommand{\cmdref}[2]{\section{\hgcmd{#1}---#2}\label{cmdref:#1}\index{\texttt{#1}, comando}} 29.135 + 29.136 +% Reference entry for a command option with long and short forms. 29.137 +\newcommand{\optref}[3]{\subsubsection{\hgopt{#1}{--#3}, también \hgopt{#1}{-#2}}} 29.138 + 29.139 +% Reference entry for a command option with only long form. 29.140 +\newcommand{\loptref}[2]{\subsubsection{opción \hgopt{#1}{--#2}}} 29.141 + 29.142 +% command to generate a footnote to be used as a translator's note 29.143 +\newcommand{\ndt}[1]{\footnote{\textbf{N. del T.} #1}} 29.144 + 29.145 + 29.146 +%%% Local Variables: 29.147 +%%% mode: latex 29.148 +%%% TeX-master: "00book" 29.149 +%%% End:
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 30.2 +++ b/es/Leame.1st Thu Jan 29 22:00:07 2009 -0800 30.3 @@ -0,0 +1,508 @@ 30.4 += Parámetros de Organización = 30.5 + 30.6 + * Se mantienen los nombres de los archivos 30.7 + * Se traduce solamente el contenido 30.8 + * Copie los archivos de en a es y tradúzcalos 30.9 + * Las gráficas son tan importantes como los archivos 30.10 + de texto, ya han sido traducidas 30.11 + * Encoding UTF-8 para las tildes, eñes y demás 30.12 + * Ancho de línea de 70 caracteres 30.13 + 30.14 += ¿Cómo contribuir? = 30.15 +Obtenga la copia : 30.16 +hg clone http://mercurial.intuxication.org/hg/mercurial_book_es/ 30.17 + 30.18 +Esto le ofrecerá un clon del repositorio en el directorio recién 30.19 +creado '''mercurial_book_es''': 30.20 + 30.21 +mercurial_book_es 30.22 +| 30.23 +|-- en 30.24 +|-- es 30.25 +|-- examples 30.26 +|-- html 30.27 +`-- sillybench 30.28 + 30.29 +El directorio de trabajo es '''es'''. 30.30 + 30.31 + 30.32 +Una vez que haya traducido o aplicado correcciones a los archivos de 30.33 +su copia local, haga un commit 30.34 + 30.35 + hg commit -m "comentario descriptivo de lo que hizo" 30.36 + 30.37 +Siempre mantenga actualizado su repositorio local 30.38 + hg pull 30.39 + hg update 30.40 + 30.41 +Hay dos formas de hacer la contribución, primero envíe un correo a 30.42 +igor@tamarapatino.org indicando lo que desea hacer, se le puede 30.43 +otorgar permiso de escritura en el repositorio, o si lo prefiere, 30.44 +puede enviar un parche (patch). Describimos a continuación los dos 30.45 +procedimientos : Repositorio Público y Parches. Es preferible el 30.46 +repositorio público frente a los parches, puesto que estos segundos 30.47 +pueden tardar en propagarse más. 30.48 + 30.49 +== Repositorio Público == 30.50 +Este sería el método preferido para que los cambios que usted haga 30.51 +automáticamente queden en el repositorio y todos los traductores 30.52 +podamos contar con la información rápidamente. 30.53 + 30.54 +Una vez que usted haya recibido la información necesaria, habiendo 30.55 +elegido su usuario y su clave podrá "publicar" (push). 30.56 + 30.57 +Como este es un sistema distribuido, después de hacer la 30.58 +consignación (commit), deberá publicarlo. 30.59 + 30.60 + hg push 30.61 + 30.62 +Se le solicitará su usuario y clave. 30.63 + 30.64 +== Parches == 30.65 +Este método exige que alguien reciba el parche y haga manualmente la 30.66 +aplicación del mismo, ese alguien es igor@tamarapatino.org por ahora, 30.67 +después de haber hecho commit en su repositorio local, revise su log. 30.68 + 30.69 + hg log | head 30.70 + 30.71 +Esta última orden le permitirá establecer la última revisión que se 30.72 +consignó en su repositorio local, su identificador de revisión tendrá 30.73 +el formato número:hash. Generaría el archivo 30.74 +/tmp/patchparahgbook.patch con la orden 30.75 + 30.76 + hg -o /tmp/patchparahgbook.patch REV 30.77 + 30.78 +donde REV es el identificador de revisión que debió haber encontrado. 30.79 + 30.80 += Traducción/Revisión = 30.81 + 30.82 +En esta sección indicamos quienes están traduciendo 30.83 +y quienes revisando lo traducido. Coloque su nombre 30.84 +para que los demás colaboradores sepan en dónde 30.85 +enfocar sus esfuerzos. 30.86 + 30.87 +Indique qué archivos está traduciendo y/o revisando en 30.88 +la lista siguiente. Cada archivo debe ser traducido y 30.89 +revisado antes de poder considerarlo terminado. El revisor 30.90 +no puede ser la misma persona que hizo la traducción. 30.91 + 30.92 +Cada traductor puede traducir o revisar el archivo que 30.93 +desee, teniendo siempre en cuenta los archivos que ya tengan 30.94 +alguien a cargo y escogiendo en la medida de lo posible 30.95 +otros que no lo tengan. Los arreglos de 'typos' y problemas 30.96 +de ortografía son siempre bienvenidos. 30.97 + 30.98 +== Archivos en proceso de traducción == 30.99 +||'''archivo''' ||'''traductor'''||'''Estado'''||'''Inicio'''|| '''Fin''' || 30.100 +|| 00book.tex || Igor Támara || 100% || 16/10/2008 || 16/10/2008 || 30.101 +|| preface.tex || Javier Rojas || 100% || 18/10/2008 || 19/10/2008 || 30.102 +|| intro.tex || Igor Támara || 100% || 08/11/2008 || 09/11/2008 || 30.103 +|| tour-basic.tex || Javier Rojas || 100% || 19/10/2008 || 27/10/2008 || 30.104 +|| tour-merge.tex || Javier Rojas || 100% || 28/10/2008 || 03/11/2008 || 30.105 +|| concepts.tex || Javier Rojas || 100% || 03/11/2008 || 23/11/2008 || 30.106 +|| daily.tex || Igor Támara || 100% || 19/10/2008 || 26/10/2008 || 30.107 +|| collab.tex || Igor Támara || 100% || 10/11/2008 || 06/12/2008 || 30.108 +|| filenames.tex || Javier Rojas || 100% || 27/11/2008 || 12/01/2008 || 30.109 +|| branch.tex || Igor Támara || 100% || 16/10/2008 || 19/10/2008 || 30.110 +|| undo.tex || Igor Támara || 100% || 26/10/2008 || 07/11/2008 || 30.111 +|| hook.tex || Javier Rojas || 100% || 01/12/2008 || 04/01/2009 || 30.112 +|| template.tex || Igor Támara || 100% || 27/12/2008 || 01/01/2009 || 30.113 +|| mq.tex || Igor Támara || 100% || 06/12/2008 || 13/12/2008 || 30.114 +|| mq-collab.tex || Javier Rojas || 100% || 04/01/2009 || 08/01/2009 || 30.115 +|| hgext.tex || Igor Támara || 100% || 13/12/2008 || 16/12/2008 || 30.116 +|| cmdref.tex || Igor Támara || 100% || 01/01/2009 || 01/01/2009 || 30.117 +|| mq-ref.tex || Igor Támara || 100% || 06/01/2009 || 10/01/2009 || 30.118 +|| srcinstall.tex || Igor Támara || 100% || 01/01/2009 || 01/01/2009 || 30.119 +|| license.tex || Igor Támara || 100% || 16/12/2008 || 16/12/2008 || 30.120 + 30.121 +== Archivos en proceso de revisión == 30.122 +||'''archivo''' || '''revisor''' ||'''Estado'''||'''Inicio'''|| '''Fin''' || 30.123 +|| 00book.tex || Javier Rojas || 100% || 18/01/2009 || 18/01/2009 || 30.124 +|| branch.tex || Javier Rojas || 100% || 25/01/2009 || 25/01/2009 || 30.125 +|| preface.tex || || || || || 30.126 +|| daily.tex || Javier Rojas || 100% || 25/01/2009 || 29/01/2009 || 30.127 +|| tour-basic.tex || || || || || 30.128 +|| undo.tex || Javier Rojas || || || || 30.129 +|| tour-merge.tex || || || || || 30.130 +|| concepts.tex || || || || || 30.131 +|| intro.tex || Javier Rojas || 100% || 12/01/2009 || 12/01/2009 || 30.132 +|| collab.tex || Javier Rojas || 0% || 29/01/2009 || || 30.133 +|| mq.tex || || || || || 30.134 +|| hgext.tex || || || || || 30.135 +|| template.tex || || || || || 30.136 +|| mq-collab.tex || || || || || 30.137 +|| mq-ref.tex || || || || || 30.138 +|| cmdref.tex || || || || || 30.139 +|| license.tex || || || || || 30.140 +|| srcinstall.tex || || || || || 30.141 + 30.142 +== Archivos terminados == 30.143 +||'''archivo''' ||'''Inicio'''|| '''Fin''' || 30.144 +|| 00book.tex || 16/10/2008 || 18/01/2009 || 30.145 +|| intro.tex || 08/11/2008 || 12/01/2009 || 30.146 +|| branch.tex || 16/10/2008 || 25/01/2009 || 30.147 +|| daily.tex || 19/10/2008 || 29/01/2009 || 30.148 + 30.149 += Unificación de Términos de Traducción = 30.150 +Por favor mantenga esta lista en orden alfabético 30.151 + 30.152 +La mayor parte del texto a continuación fue tomado del glosario de la 30.153 +traducción del libro de subversion al idioma español. 30.154 + 30.155 +Pequeño glosario de términos traducidos. Aquí deben ponerse esos 30.156 +"bonitos palabros" que tanto nos ha costado traducir para evitar 30.157 +inconsistencias en la traducción por varias personas. Normalmente 30.158 +son técnicos, pero puede incluirse cualquier "giro" o expresión que 30.159 +consideremos útil mantener y repetir a lo largo de la traducción. 30.160 +En el libro final posiblemente se añada una versión de este fichero 30.161 +como apéndice. 30.162 + 30.163 +Para incluir algo, hay que especificar la expresión en inglés, su 30.164 +versión traducida, y una pequeña explicación como justificación. 30.165 + 30.166 + Alice: Alicia 30.167 + Anne: Ana 30.168 + Back out: Retroceder 30.169 + Binary test: Prueba binaria 30.170 + Bob : Roberto 30.171 + Branch: Rama 30.172 + Bug: Fallo 30.173 + Build Script: Guión de construcción 30.174 + Builtin: integrada/o 30.175 + Bundle: Agrupamiento 30.176 + Bundled: Incluído o agrupado 30.177 + Changelog: Bitácora de Cambios 30.178 + Changeset: Conjunto de Cambios 30.179 + Command: Orden 30.180 + Commit: Consignar 30.181 + Core: alma 30.182 + Directory: Directorio 30.183 + Escape Sequence: Secuencia de control 30.184 + File: fichero 30.185 + Filelog: fichero de registro 30.186 + Fold: Integrar 30.187 + Fork: Bifurcación 30.188 + Hash: No se traduce 30.189 + Head: Principal. En el contexto de revisiones HEAD se sugiere usar "frente" 30.190 + Hook: Gancho 30.191 + Merge: Fusión 30.192 + Milestone: Etapa 30.193 + Mistake: Equivocación, cometida por un humano 30.194 + Output: salida o despliegue 30.195 + Patch: Parche 30.196 + Path: Ruta de archivo 30.197 + Pointer: apuntador 30.198 + Pop: Sustraer, la contraparte push, será publicar 30.199 + Probe: Sondeo 30.200 + Pull: Jalar 30.201 + Push: Publicar. En el contexto de parches introducir. 30.202 + Queue: Cola 30.203 + Release: Versión o liberación de versión 30.204 + Revlog: Bitácora de revisiones 30.205 + Roll back: NO se traduce Ver más abajo 30.206 + Snapshot: instantánea 30.207 + Snippet: Recorte de código 30.208 + Stack: pila 30.209 + Stripped: 30.210 + Sprint: sprint 30.211 + Tarball: paquete de cambios 30.212 + Timestamp : marca de tiempo 30.213 + Tip: punta 30.214 + Update: actualización 30.215 + Upstream: principal, mantenedor principal. De acuerdo al contexto. 30.216 + 30.217 +abort -> cancelar 30.218 + 30.219 +ancestry -> ascendencia 30.220 + La traducción literal concuerda con el significado que se le 30.221 + da al mismo término en la jerga de Subversion. 30.222 + 30.223 +API, GUI -> no se traduce 30.224 + La primera vez que aparecen, poner nota del traductor indicando 30.225 + qué significan las siglas y su traducción al castellano. De 30.226 + hecho, verificar la aparición de las notas de traductor en el 30.227 + sitio correcto debería ser una entrada del fichero TODO... 30.228 + 30.229 +back-end -> ??? 30.230 + Se refiere al término opuesto de front-end. En el octavo 30.231 + capítulo se usa al menos tres veces para referirse al "motor" 30.232 + que hay detrás de la capa de base de datos. Hmmm... pero motor 30.233 + suena raro... 30.234 + 30.235 +backup -> copia de seguridad 30.236 + Obtenido del glosario ORCA. 30.237 + 30.238 +Blanket Access Control -> Control de acceso simple 30.239 + Por ahora no se me ocurre mejor traducción. Aquí blanket se 30.240 + refiere a un control muy genérico, con poca granularidad. 30.241 + 30.242 +branching and merging -> crear ramas y fusionarlas 30.243 + Aunque branch está bien traducido como rama o rama de desarrollo 30.244 + (en su versión "verbose"), no hay forma de hacer de un sustantivo 30.245 + un verbo. Por lo tanto, se crean, borran y fusionan ramas. 30.246 + 30.247 +browse -> navegar 30.248 + Usado con frecuencia para navegar por directorios o repositorios. 30.249 + 30.250 +build -> comodín 30.251 + No es que se traduzca como comodín, sino que en función del 30.252 + contexto es una de esas palabras que significan muchas cosas y 30.253 + no es posible traducirla literalmente. Por ejemplo, cuando se 30.254 + usa como verbo se suele referir a compilar código fuente. En 30.255 + cambio, cuando se usa como sustantivo se suele referir a una 30.256 + versión particular del fichero binario ejecutable de un software, 30.257 + resultado de una compilación previa. Cuidado con esto. Anotar 30.258 + aquí traducciones realizadas para comparar. 30.259 + 30.260 + ...using and building Subversion... 30.261 + ...usando y compilando Subversion... 30.262 + 30.263 +changeset -> ??? 30.264 + Aparentemente conjunto de cambios. No puede ser traducido 30.265 + como parche, el libro inglés indica que un "changeset" es un 30.266 + parche con nombre único. Por ahora dejar en "changeset", ya se 30.267 + buscará algo en el futuro. Para ver la descripción del libro, 30.268 + buscar en ch04.xml la frase "Subversion y los changesets". 30.269 + 30.270 +cheap copy -> copia ligera 30.271 + Otras posibilidades barajadas son copia barata o liviana. 30.272 + Veremos si en el futuro éstas suenan mejor. 30.273 + 30.274 +click -> haga clic, pulse 30.275 + Traducción obtenida del glosario. Parece ser que click sólo se 30.276 + deja tal cual cuando se refiere a un sonido mecánico. Cuando 30.277 + se refiere a pulsar el botón del ratón se traduce como clic. 30.278 + 30.279 +CVS -> No se traduce 30.280 + 30.281 +DAV share -> recurso DAV compartido 30.282 + No tengo ni idea de lo que es un DAV share, así que cuando me 30.283 + entere (o alguien lo haga), que cambie esta entrada del glosario. 30.284 + 30.285 +directory -> directorio 30.286 + Entre carpeta y directorio se prefiere directorio. 30.287 + 30.288 +email -> correo electrónico 30.289 + Entre las posibilidades de dejar la palabra tal cual, añadir un 30.290 + guión (e-mail) y poner la traducción, se prefiere la traducción 30.291 + completa. 30.292 + 30.293 +FAQ -> FAQ 30.294 + Se deja tal cual pues se explica en el primer párrafo del prólogo 30.295 + como una nota del traductor, y porque es muy frecuente ver su 30.296 + uso en español. PyRF, PUFs o PFs son realmente desconcertantes. 30.297 + 30.298 +file -> fichero 30.299 + Entre archivo y fichero se prefiere fichero. 30.300 + 30.301 +file path -> ruta del fichero 30.302 + Cuando se ve path a secas, la forma más común de traducirlo 30.303 + es decir ruta a secas igualmente. Bueno, el glosario de ORCA 30.304 + también da como válidos camino y trayectoria. A ser posible 30.305 + usar ruta si el contexto de la frase así lo favorece, en caso 30.306 + contrario probar con camino o trayectoria. 30.307 + 30.308 +hash table -> tabla hash 30.309 + Sugerido por Miguel Pérez Ibars. También encontrado en el 30.310 + glosario ORCA. 30.311 + 30.312 +history -> Depende del contexto. Cuando se use en el contexto del repositorio 30.313 + (the history of the repository), debe usarse el término historial. En otro 30.314 + caso, historia. Valga anotar que ambas traducciones son aceptadas (al menos 30.315 + en wordreference.com). 30.316 + 30.317 +hook, to hook -> gancho, enganchar 30.318 + Usado en terminología de programación para indicar que el usuario 30.319 + tiene un mecanismo estándar para modificar el comportamiento de 30.320 + un dispositivo existente. Un ejemplo a nivel de programación 30.321 + son las funciones "callback" que se pasan como parámetros, 30.322 + o a nivel de sistema, scripts que existen en un directorio 30.323 + concreto y que se ejecutan por el servidor de Subversion para 30.324 + realizar tareas personalizadas por el administrador. 30.325 + 30.326 +ignore pattern -> ignorar patrones, pero patrones de exclusión 30.327 + Subversion permite que ciertas opciones almacenen patrones 30.328 + con los que se ignoran ficheros no versionados. Cuando la 30.329 + frase original usa el verbo, se puede traducir como ignorar 30.330 + directamente, pero cuando se usa a modo de sustantivo, 30.331 + es mejor traducirlo como "patrón de exclusión" en lugar de 30.332 + "patrón a ignorar". 30.333 + 30.334 +language -> lenguaje o idioma 30.335 + Precisamente para diferenciar si nos estamos refiriendo a un 30.336 + lenguaje de programación o a un lenguaje hablado por humanos, 30.337 + se usará idioma en este último caso. 30.338 + 30.339 +language binding, SWIG binding, wrapper -> interfaz, enlace, ligadura, envoltorio... 30.340 + Dependiendo del contexto, y desde un punto de vista personal, 30.341 + se puede traducir esta palabra de muchas maneras. Una manera 30.342 + genérica es decir "Interfaz con el lenguaje X", o "Ligadura con 30.343 + el lenguaje X". Habitualmente, cuando se habla de una interfaz, 30.344 + se está hablando de un binding ligero, o que únicamente permite 30.345 + a hacer llamadas a funciones del lenguaje de programación A 30.346 + desde el lenguaje de programación B. 30.347 + 30.348 + En cambio, se suele hablar de wrapper cuando el código entre 30.349 + el lenguaje A y B es algo más complejo, o adapta el estilo de 30.350 + programación del lenguaje A al del lenguaje B. Un ejemplo de esto 30.351 + último sería una librería en C cuyo binding en Perl/Ruby/Python 30.352 + fuese orientado a objetos. 30.353 + 30.354 + Aparte, wrapper también se usa cuando se habla de una función 30.355 + o librería que engloba o asimila otra menor, con el propósito 30.356 + de extender su funcionalidad o hacerla más fácil de usar 30.357 + de cara al usuario, sin necesidad de cruzar ninguna barrera 30.358 + "intra-lenguaje". 30.359 + 30.360 + Por lo tanto, hay que decidir con cuidado el contexto de la 30.361 + palabra binding o wrapper, y escoger una. En el capítulo octavo 30.362 + hay varios usos, aunque como son relativos a SWIG, se habla de 30.363 + interfaces o envoltorios simplificados, puesto que se generan 30.364 + de manera automática y no hay ninguna "conversión" en el estilo 30.365 + de uso. 30.366 + 30.367 +lazy copy -> copia vaga 30.368 + Horrible traducción literal. ¿Sugerencias? 30.369 + copia perezosa 30.370 + 30.371 +location (repository) -> ubicación (del repositorio) 30.372 + Cuidado, no traducir como localización, que es la acción y 30.373 + efecto de localizar. 30.374 + 30.375 +log, log message -> informe de cambios, mensaje del informe de cambios 30.376 + Traducción extraída del manual de CVS en español. La traducción 30.377 + de "log message" es muy larga, pero únicamente porque no se 30.378 + tiene contexto alguno. Con contexto suele ser posible omitir 30.379 + la palabra informe si se considera apropiado. 30.380 + 30.381 +memory pool -> área de memoria 30.382 + Traducción temporal hasta que se revise algún libro en castellano 30.383 + de programación que use el mismo término. 30.384 + 30.385 +merge -> fusionar cambios, fusión 30.386 + Obtenida referencia del manual de CVS en castellano, la otra 30.387 + alternativa obvia para traducir merge es mezclar. No obstante, 30.388 + mezclar tiene una connotación de azar al realizar la mezcla. Se 30.389 + mezclan líquidos, ingredientes, etc. En cambio, un "merge" es 30.390 + cualquier cosa menos un proceso realizado al azar (especialmente 30.391 + si ha habido conflictos). En caso de traducir como sustantivo, 30.392 + fusión vuelve a "sonar mejor" que mezcla, que por alguna razón me 30.393 + suena a un combustible especial usado en vehículos de transporte. 30.394 + 30.395 +namespace -> espacio de nombrado, 30.396 + Tecnicismo del C++, obtenido de la traducción del libro 30.397 + "Pensar en C++", en concreto la sección 3.2 disponible en 30.398 + http://arco.inf-cr.uclm.es/~dvilla/pensar_en_C++/ch02s03.html#id2589039. 30.399 + 30.400 +open source -> código fuente abierto 30.401 + Referencia: http://es.tldp.org/ORCA/glosario.html#O 30.402 + 30.403 +plugins -> módulos 30.404 + El término fue extraído del glosario de ORCA. 30.405 + 30.406 +repository -> repositorio 30.407 + No hay mucha alternativa, ¿verdad? 30.408 + 30.409 +roll back -> No se traduce 30.410 + El significado igual que en los ambientes 30.411 + de sistemas manejadores de bases de datos se refiere a la atomicidad 30.412 + e integridad al devolver un conjunto de acciones que permitan dejar 30.413 + el repositorio en un estado consistente previo. 30.414 + 30.415 +repository layou t-> estructura del repositorio En referencia a cómo 30.416 + están organizados los directorios. 30.417 + 30.418 +schedule -> programa o planifica 30.419 + Parece más correcta la opción programa, en el sentido de pensar en 30.420 + hacer algo. 30.421 + schedule foo to be added -> programa la adición de foo 30.422 + 30.423 +switch -> cambiar 30.424 + Únicamente cuando se habla del comando svn switch, no como la 30.425 + palabra switch aislada, que significa parámetro o interruptor. 30.426 + En el contexto de svn switch, traducirlo como cambiar. Quizás 30.427 + traducir como reubicar una vez haya suficiente material traducido 30.428 + y una lectura final sugiera una u otra traducción. 30.429 + 30.430 +tag, tagging -> etiqueta, etiquetar 30.431 + Expresión ya común en español. 30.432 + 30.433 +three-way differencing program -> programa de diferenciación a tres bandas 30.434 + Una diferenciación "normal" es generar las diferencias entre 30.435 + dos ficheros. Una diferenciación a tres bandas es comparar las 30.436 + diferencias entre tres ficheros, y se usa cuando se intentan 30.437 + fusionar los cambios de una copia local junto con los cambios 30.438 + recibidos del repositorio (por ejemplo, otra persona ha cambiado 30.439 + el fichero sobre el que trabajábamos). 30.440 + 30.441 +timestamp, datestamp -> marca de tiempo, fecha y hora 30.442 + Esa traducción viene del ORCA. No obstante en muchos casos es 30.443 + más claro traducirla como "fecha de fichero" o "fecha" a secas. 30.444 + Ejemplo: ...will show the modification timestamp. -> mostrará 30.445 + la fecha de modificación. Decir "mostrará la marca de tiempo de 30.446 + la modificación" o algo así es una traducción demasiado literal, 30.447 + así que ojo con el contexto. 30.448 + 30.449 +track -> seguir, monitorear 30.450 + este término suele ser usado cuando se habla de archivos, y de llevar la 30.451 + pista o monitorear los cambios en un archivo. 30.452 + 30.453 +trunk -> tronco 30.454 + Se refiere al nombre que recibe la línea de desarrollo 30.455 + principal del repositorio que no está asociada a ninguna rama 30.456 + en particular. Traducción obtenida del manual de CVS en español. 30.457 + 30.458 +Unix-like systems -> sistemas tipo unix 30.459 + 30.460 +URL -> No se traduce 30.461 + 30.462 +working copy -> copia (de trabajo) local/activa 30.463 + Traducción similar a la de "commit data" (razonamiento 30.464 + cliente-servidor). 30.465 + 30.466 += Términos a no-usar = 30.467 +Evite el uso de estos términos en la traducción aún si son de uso 30.468 +común para usted; el consenso general de la comunidad hispana puede 30.469 +ser diferente del que usted tenga ;) 30.470 + 30.471 + * "archivo". Use "fichero" en su lugar. 30.472 + * "carpeta". Use "directorio". 30.473 + * "la historia". Use "el historial" (por supuesto, cuando se refiera al 30.474 + historial del repositorio) 30.475 + 30.476 += Diferencias de redacción = 30.477 +Hay varias expresiones que pueden terminar siendo traducidas de formas 30.478 +diferentes por los traductores, y que aún siendo ambas correctas, ponen en 30.479 +evidencia que el trabajo fue llevado a cabo por varias personas y que el estilo 30.480 +que ellas usan difiere. Una vez terminada la traducción habrá que buscar cuáles 30.481 +son éstos términos y decidirse por uno solo de ellos. A continuación se presenta 30.482 +una lista de los términos o expresiones encontrados hasta ahora 30.483 + 30.484 + * comando - orden. Ambos son la traducción para "command". Parece que la 30.485 + traducción más adecuada es "comando" 30.486 + (http://www.wordreference.com/es/translation.asp?tranword=command) 30.487 + * kernel - núcleo. 30.488 + * Colas de Mercurial - colas de Mercurial. Creo que lo mejor es revisar qué 30.489 + usó el autor (y rogar que él no haya sido inconsistente :P) 30.490 + * armar - compilar - construir. Build, compile. Más que todo "build" 30.491 + * daemonio - demonio. daemon 30.492 + * kernel - núcleo. 30.493 + * la URL - el URL 30.494 + 30.495 += Notas del traductor = 30.496 +Por favor use el comando \ndt para insertar notas del traductor. Este 30.497 +comando requiere un argumento. Por ejemplo: \ndt{Del inglés del original.} 30.498 + 30.499 += Para compilar = 30.500 +He aquí algunas dependencias para Debian: 30.501 + 30.502 +apt-get install texlive-latex-extra tex4ht diffstat patchutils \ 30.503 + inkscape graphviz texlive-pdfetex 30.504 + 30.505 += Traductores = 30.506 +Por favor mantenga esta lista en orden alfabético de acuerdo al 30.507 +apellido. 30.508 + 30.509 + * Javier Rojas <jerojasro@devnull.li> 30.510 + * Igor Támara <igor@tamarapatino.org> 30.511 + * Su nombre <su@e.mail>
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 31.2 +++ b/es/Makefile Thu Jan 29 22:00:07 2009 -0800 31.3 @@ -0,0 +1,223 @@ 31.4 +# This makefile requires GNU make. 31.5 + 31.6 +sources := \ 31.7 + 00book.tex \ 31.8 + 99book.bib \ 31.9 + 99defs.tex \ 31.10 + build_id.tex \ 31.11 + branch.tex \ 31.12 + cmdref.tex \ 31.13 + collab.tex \ 31.14 + concepts.tex \ 31.15 + daily.tex \ 31.16 + filenames.tex \ 31.17 + hg_id.tex \ 31.18 + hgext.tex \ 31.19 + hook.tex \ 31.20 + intro.tex \ 31.21 + mq.tex \ 31.22 + mq-collab.tex \ 31.23 + mq-ref.tex \ 31.24 + preface.tex \ 31.25 + srcinstall.tex \ 31.26 + template.tex \ 31.27 + tour-basic.tex \ 31.28 + tour-merge.tex \ 31.29 + undo.tex 31.30 + 31.31 +image-sources := \ 31.32 + feature-branches.dot \ 31.33 + filelog.svg \ 31.34 + kdiff3.png \ 31.35 + metadata.svg \ 31.36 + mq-stack.svg \ 31.37 + note.png \ 31.38 + revlog.svg \ 31.39 + snapshot.svg \ 31.40 + tour-history.svg \ 31.41 + tour-merge-conflict.svg \ 31.42 + tour-merge-merge.svg \ 31.43 + tour-merge-pull.svg \ 31.44 + tour-merge-sep-repos.svg \ 31.45 + undo-manual.dot \ 31.46 + undo-manual-merge.dot \ 31.47 + undo-non-tip.dot \ 31.48 + undo-simple.dot \ 31.49 + wdir.svg \ 31.50 + wdir-after-commit.svg \ 31.51 + wdir-branch.svg \ 31.52 + wdir-merge.svg \ 31.53 + wdir-pre-branch.svg 31.54 + 31.55 +image-dot := $(filter %.dot,$(image-sources)) 31.56 +image-svg := $(filter %.svg,$(image-sources)) 31.57 +image-png := $(filter %.png,$(image-sources)) 31.58 + 31.59 +image-pdf := $(image-dot:%.dot=%.pdf) $(image-svg:%.svg=%.pdf) $(image-png) 31.60 +image-html := $(image-dot:%.dot=%.png) $(image-svg:%.svg=%.png) $(image-png) 31.61 + 31.62 +example-sources := \ 31.63 + backout \ 31.64 + bisect \ 31.65 + branching \ 31.66 + branch-named \ 31.67 + branch-repo \ 31.68 + cmdref \ 31.69 + daily.copy \ 31.70 + daily.files \ 31.71 + daily.rename \ 31.72 + daily.revert \ 31.73 + extdiff \ 31.74 + filenames \ 31.75 + hook.msglen \ 31.76 + hook.simple \ 31.77 + hook.ws \ 31.78 + issue29 \ 31.79 + mq.guards \ 31.80 + mq.qinit-help \ 31.81 + mq.dodiff \ 31.82 + mq.id \ 31.83 + mq.tarball \ 31.84 + mq.tools \ 31.85 + mq.tutorial \ 31.86 + rename.divergent \ 31.87 + rollback \ 31.88 + tag \ 31.89 + template.simple \ 31.90 + template.svnstyle \ 31.91 + tour \ 31.92 + tour-merge-conflict 31.93 + 31.94 +example-prereqs := \ 31.95 + /usr/bin/merge 31.96 + 31.97 +dist-sources := \ 31.98 + ../html/hgicon.png \ 31.99 + ../html/index.html.var \ 31.100 + ../html/index.en.html \ 31.101 + ../html/index.es.html 31.102 + 31.103 +latex-options = \ 31.104 + -interaction batchmode \ 31.105 + -output-directory $(dir $(1)) \ 31.106 + -jobname $(basename $(notdir $(1))) 31.107 + 31.108 +hg = $(shell which hg) 31.109 + 31.110 +hg-id = $(shell hg parents --template '{node|short}, fechado {date|isodate},\n') 31.111 + 31.112 +hg-version = $(shell hg version -q | \ 31.113 + sed 's,.*(versión \(unknown\|[a-f0-9+]*\)),\1,') 31.114 + 31.115 +all: pdf html 31.116 + 31.117 +pdf: pdf/hgbook.pdf 31.118 + 31.119 +define pdf 31.120 + mkdir -p $(dir $@) 31.121 + TEXINPUTS=$(dir $<): pdflatex $(call latex-options,$@) $< || (rm -f $@; exit 1) 31.122 + cp 99book.bib $(dir $@) 31.123 + cd $(dir $@) && bibtex $(basename $(notdir $@)) 31.124 + cd $(dir $@) && makeindex $(basename $(notdir $@)) 31.125 + TEXINPUTS=$(dir $<): pdflatex $(call latex-options,$@) $< || (rm -f $@; exit 1) 31.126 + TEXINPUTS=$(dir $<): pdflatex $(call latex-options,$@) $< || (rm -f $@; exit 1) 31.127 + if grep 'Reference.*undefined' $(@:.pdf=.log); then exit 1; fi 31.128 +endef 31.129 + 31.130 +pdf/hgbook.pdf: $(sources) examples $(image-pdf) 31.131 + $(call pdf) 31.132 + 31.133 +html: onepage split 31.134 + 31.135 +onepage: $(htlatex) html/onepage/hgbook.html html/onepage/hgbook.css $(image-html:%=html/onepage/%) 31.136 + 31.137 +html/onepage/%: % 31.138 + cp $< $@ 31.139 + 31.140 +split: $(htlatex) html/split/hgbook.html html/split/hgbook.css $(image-html:%=html/split/%) 31.141 + 31.142 +html/split/%: % 31.143 + cp $< $@ 31.144 + 31.145 +# This is a horrible hack to work around the fact that the htlatex 31.146 +# command in tex4ht is itself a horrible hack. I really don't want to 31.147 +# include verbatim the big wad of TeX that is repeated in that script, 31.148 +# but I've given up and run a hacked copy as htlatex.book here. 31.149 + 31.150 +define htlatex 31.151 + mkdir -p $(dir $(1)) 31.152 + cp 99book.bib $(dir $(1)) 31.153 + TEXINPUTS=$(dir $(2)): ./htlatex.book $(2) "bookhtml,html4-uni,$(3)" " -cunihtf -utf8" "$(dir $(1))" "$(call latex-options,$(1))" || (rm -f $(1); exit 1) 31.154 + cd $(dir $(1)) && tex4ht -f/$(basename $(notdir $(1))) -cvalidate -cunihtf 31.155 + cd $(dir $(1)) && t4ht -f/$(basename $(notdir $(1))) 31.156 + ./fixhtml.py $(dir $(1))/*.html 31.157 + rm $(dir $(1))/hgbook.css 31.158 +endef 31.159 + 31.160 +html/onepage/hgbook.html: $(sources) examples $(image-html) bookhtml.cfg 31.161 + $(call htlatex,$@,$<) 31.162 + 31.163 +html/split/hgbook.html: $(sources) examples bookhtml.cfg 31.164 + $(call htlatex,$@,$<,2) 31.165 + 31.166 +# Produce 90dpi PNGs for the web. 31.167 + 31.168 +%.png: %.svg fixsvg 31.169 + ./fixsvg $< 31.170 + inkscape -D -e $@ $<-tmp.svg 31.171 + rm $<-tmp.svg 31.172 + 31.173 +%.svg: %.dot 31.174 + dot -Tsvg -o $@ $< 31.175 + 31.176 +# Produce eps & pdf for the pdf 31.177 + 31.178 +%.pdf: %.eps 31.179 + epstopdf $< 31.180 + 31.181 +%.eps: %.svg 31.182 + ./fixsvg $< 31.183 + inkscape -E $@ $<-tmp.svg 31.184 + rm $<-tmp.svg 31.185 + 31.186 +%.eps: %.dot 31.187 + dot -Tps -o $@ $< 31.188 + 31.189 +examples: $(example-prereqs) examples/.run 31.190 + 31.191 +examples/.run: $(example-sources:%=examples/%.run) 31.192 + touch examples/.run 31.193 + 31.194 +examples/%.run: examples/% examples/run-example 31.195 + cd examples && ./run-example $(notdir $<) 31.196 + 31.197 +changelog := $(wildcard ../.hg/store/00changelog.[id]) 31.198 +ifeq ($(changelog),) 31.199 +changelog := $(wildcard ../.hg/00changelog.[id]) 31.200 +endif 31.201 + 31.202 +build_id.tex: $(changelog) 31.203 + echo -n '$(hg-id)' > build_id.tex 31.204 + 31.205 +hg_id.tex: $(hg) 31.206 + echo -n '$(hg-version)' > hg_id.tex 31.207 + 31.208 +clean: 31.209 + rm -rf dist html pdf \ 31.210 + $(image-dot:%.dot=%.pdf) \ 31.211 + $(image-dot:%.dot=%.png) \ 31.212 + $(image-svg:%.svg=%.pdf) \ 31.213 + $(image-svg:%.svg=%.png) \ 31.214 + examples/*.{lxo,run} examples/.run build_id.tex hg_id.tex 31.215 + 31.216 +install: pdf split $(dist-sources) 31.217 + rm -rf dist 31.218 + mkdir -p dist 31.219 + cp pdf/hgbook.pdf dist 31.220 + cp html/split/*.{css,html,png} dist 31.221 + cp html/onepage/hgbook.html dist/onepage.html 31.222 + ln -s index.es.html dist/index.html 31.223 + cp $(dist-sources) dist 31.224 + 31.225 +rsync: install 31.226 + rsync -avz --delete dist/ ikks@sulaco.devnull.li:public_html/hgbook/
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 32.2 +++ b/es/bookhtml.cfg Thu Jan 29 22:00:07 2009 -0800 32.3 @@ -0,0 +1,1 @@ 32.4 +../en/bookhtml.cfg 32.5 \ No newline at end of file
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 33.2 +++ b/es/branch.tex Thu Jan 29 22:00:07 2009 -0800 33.3 @@ -0,0 +1,412 @@ 33.4 +%% vim: tw=70 encoding=utf8 33.5 +\chapter{Administración de versiones y desarrollo ramificado} 33.6 +\label{chap:branch} 33.7 + 33.8 +Mercurial ofrece varios mecanismos que le permiten administrar un 33.9 +proyecto que avanza en múltiples frentes simultáneamente. Para 33.10 +entender estos mecanismos, demos un vistazo a la estructura usual de 33.11 +un proyecto de software. 33.12 + 33.13 +Muchos proyectos de software liberan una versión ``mayor'' que contiene 33.14 +nuevas características substanciales. En paralelo, pueden liberar 33.15 +versiones ``menores''. Usualmente éstas son idénticas a las 33.16 +versiones mayores en las cuales están basadas, pero con arreglos para 33.17 +algunos fallos. 33.18 + 33.19 +En este capítulo, comenzaremos hablando de cómo mantener registro de 33.20 +etapas del proyecto como las liberaciones de una 33.21 +versión. Continuaremos hablando del flujo de trabajo entre las 33.22 +diferentes fases de un proyecto, y cómo puede ayudar Mercurial a 33.23 +aislar y administrar tal trabajo. 33.24 + 33.25 +\section{Dar un nombre persistente a una revisión} 33.26 + 33.27 +Cuando usted decide otorgar a una revisión el nombre particular de una 33.28 +``versión'', es buena idea grabar la identidad de tal revisión. 33.29 +Esto le permitirá reproducir dicha versión en una fecha posterior, 33.30 +para cualquiera que sea el 33.31 +propósito que se tenga en ese momento (reproducir un fallo, portar 33.32 +a una nueva plataforma, etc). 33.33 +\interaction{tag.init} 33.34 + 33.35 +Mercurial le permite dar un nombre permanente a cualquier revisión 33.36 +usando la orden \hgcmd{tag}. Sin causa de sorpresa, esos nombres se llaman 33.37 +``tags'' (etiquetas). 33.38 +\interaction{tag.tag} 33.39 + 33.40 +Una etiqueta no es más que un ``nombre simbólico'' para una revisión. Las 33.41 +etiquetas existen únicamente para su conveniencia, brindándole una forma 33.42 +permanente y sencilla de referirse a una revisión; Mercurial no 33.43 +interpreta de ninguna manera los nombres de las etiquetas que usted use. 33.44 +Mercurial tampoco impone restricción alguna al nombre de una etiqueta, más 33.45 +allá de lo necesario para asegurar que una etiqueta pueda procesarse sin 33.46 +ambigüedades. El nombre de una etiqueta no puede tener ninguno de los 33.47 +siguientes caracteres: 33.48 +\begin{itemize} 33.49 +\item Dos puntos (ASCII 58, ``\texttt{:}'') 33.50 +\item Retorno de carro (return) (ASCII 13, ``\Verb+\r+'') 33.51 +\item Nueva línea (ASCII 10, ``\Verb+\n+'') 33.52 +\end{itemize} 33.53 + 33.54 +Puede usar la orden \hgcmd{tags} para ver las etiquetas presentes en 33.55 +su repositorio. Al desplegarse, cada revisión marcada se identifica 33.56 +primero con su nombre, después con el número de revisión y finalmente con 33.57 +un hash único de la revisión. 33.58 +\interaction{tag.tags} 33.59 +Note que \texttt{tip} aparece en en listado generado por \hgcmd{tags}. La etiqueta 33.60 +\texttt{tip} es una etiqueta ``flotante'' especial, que identifica siempre 33.61 +la revisión más reciente en el repositorio. 33.62 + 33.63 +Al desplegar la orden \hgcmd{tags}, las etiquetas se listan en orden 33.64 +inverso, por número de revisión. Lo que significa usualmente que las 33.65 +etiquetas más recientes se listan antes que las más antiguas. También 33.66 +significa que la etiqueta \texttt{tip} siempre aparecerá como primera 33.67 +etiqueta listada al desplegar la orden \hgcmd{tags}. 33.68 + 33.69 +Cuando usted ejecuta \hgcmd{log}, si se muestra una revisión que tenga 33.70 +etiquetas asociadas a ella, se imprimirán tales etiquetas. 33.71 +\interaction{tag.log} 33.72 + 33.73 +Siempre que requiera indicar un~ID de revisión a una orden de 33.74 +Mercurial, aceptará un nombre de etiqueta en su lugar. Internamente, 33.75 +Mercurial traducirá su nombre de etiqueta en el~ID de revisión 33.76 +correspondiente, y lo usará. 33.77 +\interaction{tag.log.v1.0} 33.78 + 33.79 +No hay límites en la cantidad de etiquetas por repositorio, o la cantidad 33.80 +de etiquetas que una misma revisión pueda tener. Siendo prácticos, no es 33.81 +muy buena idea tener ``demasiadas'' (la cantidad variará de un 33.82 +proyecto a otro), debido a que la intención es ayudarle a encontrar 33.83 +revisiones. Si tiene demasiadas etiquetas, la facilidad de usarlas 33.84 +para identificar revisiones disminuirá rápidamente. 33.85 + 33.86 +Por ejemplo, si su proyecto tiene etapas (milestones) frecuentes, de pocos 33.87 +días, es perfectamente razonable asignarle una etiqueta a cada una de 33.88 +ellas. Pero si tiene un sistema de construcción automática de binarios 33.89 +que asegura que cada revisión puede generarse limpiamente, estaría 33.90 +introduciendo mucho ruido si se usara una etiqueta para cada generación 33.91 +exitosa. Más bien, podría usar tags para generaciones fallidas 33.92 +(\textexclamdown en 33.93 +caso de que estas sean raras!), o simplemente evitar las etiquetas para 33.94 +llevar cuenta de la posibilidad de generación de binarios. 33.95 + 33.96 + 33.97 +Si quiere eliminar una etiqueta que no desea, use 33.98 +\hgcmdargs{tag}{--remove}. 33.99 +\interaction{tag.remove} 33.100 +También puede modificar una etiqueta en cualquier momento, para que 33.101 +identifique una revisión distinta, simplemente usando una nueva orden 33.102 +\hgcmd{tag}. Deberá usar la opción \hgopt{tag}{-f} para indicarle a 33.103 +Mercurial que \emph{realmente} desea actualizar la etiqueta. 33.104 +\interaction{tag.replace} 33.105 +De todas maneras habrá un registro permanente de la antigua identidad 33.106 +de la etiqueta, pero Mercurial no la usará. Por lo tanto no hay 33.107 +problema al marcar con una etiqueta una revisión incorrecta; lo único 33.108 +que debe hacer es mover la etiqueta hacia la revisión correcta tan 33.109 +pronto como localice el error. 33.110 + 33.111 +Mercurial almacena las etiquetas en un fichero controlado por revisiones en 33.112 +su repositorio. Si ha creado etiquetas, las encontrará en un fichero 33.113 +llamado \sfilename{.hgtags}. Cuando invoca la orden \hgcmd{tag}, 33.114 +Mercurial modifica este fichero, y hace la consignación del cambio al 33.115 +mismo automáticamente. Esto significa que cada vez que ejecuta 33.116 +\hgcmd{tag}, verá un conjunto de cambios correspondiente en la salida 33.117 +de \hgcmd{log}. 33.118 +\interaction{tag.tip} 33.119 + 33.120 +\subsection{Manejo de conflictos entre etiquetas durante una fusión} 33.121 + 33.122 +Usualmente no tendrá que preocuparse por el fichero \sfilename{.hgtags}, 33.123 +pero a veces hace su aparición durante una fusión. El formato del 33.124 +fichero es sencillo: Consiste de una serie de líneas. Cada línea 33.125 +comienza con un hash de conjunto de cambios, seguido por un espacio, 33.126 +seguido por el nombre de una etiqueta. 33.127 + 33.128 +Si está resolviendo un conflicto en el fichero \sfilename{.hgtags} 33.129 +durante una fusión, hay un detalle para tener en cuenta al modificar 33.130 +el fichero \sfilename{.hgtags}: 33.131 +cuando Mercurial procesa las etiquetas en el repositorio, \emph{nunca} 33.132 +lee la copia de trabajo del fichero \sfilename{.hgtags}. En cambio, 33.133 +lee la versión \emph{consignada más reciente} del fichero. 33.134 + 33.135 +Una consecuencia desafortunada de este diseño es que usted no puede 33.136 +verificar que su fichero \sfilename{.hgtags} fusionado sea correcto hasta 33.137 +\emph{después} de haber consignado un cambio. Así que si se 33.138 +encuentra resolviendo un conflicto en \sfilename{.hgtags} durante una 33.139 +fusión, asegúrese de ejecutar la orden \hgcmd{tags} después de 33.140 +consignar. Si encuentra un error en el fichero \sfilename{.hgtags}, 33.141 +la orden reportará el lugar del error, que podrá arreglar y después 33.142 +consignar. Posteriormente ejecute de nuevo la orden \hgcmd{tags} para 33.143 +asegurarse de que su arreglo fue aplicado correctamente . 33.144 + 33.145 +\subsection{Etiquetas y clonado} 33.146 + 33.147 +Puede haber notado que la orden \hgcmd{clone} tiene la opción 33.148 +\hgopt{clone}{-r} que le permite clonar una copia exacta del 33.149 +repositorio hasta un conjunto de cambios específico. El nuevo clon no 33.150 +tendrá historial posterior a la revisión que usted haya 33.151 +especificado. Esto tiene una interacción con etiquetas que puede 33.152 +sorprender a los desprevenidos. 33.153 + 33.154 +Recuerde que una etiqueta se almacena como una revisión al fichero 33.155 +\sfilename{.hgtags}, así que cuando usted crea una etiqueta, el 33.156 +conjunto de cambios en el cual ésta se almacena necesariamente se 33.157 +refiere a un conjunto de cambios anterior. Cuando ejecuta 33.158 +\hgcmdargs{clone}{-r foo} para clonar un repositorio hasta la etiqueta 33.159 +\texttt{foo}, el nuevo clon \emph{no contendrá el historial que creo 33.160 +la etiqueta} que usó para clonar el repositorio. El resultado es que tendrá 33.161 +exactamente el subconjunto correcto del historial del proyecto en el 33.162 +nuevo repositorio, pero, \emph{no} la etiqueta que podría haber esperado. 33.163 + 33.164 +\subsection{Cuando las etiquetas permanentes son demasiado} 33.165 + 33.166 +Dado que las etiquetas de Mercurial están controladas por revisiones y se 33.167 +llevan en el historial del proyecto, todas las personas involucradas 33.168 +verán las etiquetas que usted haya creado. El hecho de dar nombres a las 33.169 +revisiones tiene usos más allá que simplemente hacer notar que la 33.170 +revisión \texttt{4237e45506ee} es realmente \texttt{v2.0.2}. Si está 33.171 +tratando de encontrar un fallo sutil, posiblemente desearía colocar una 33.172 +etiqueta recordándole algo como ``Ana vio los síntomas en esta revisión''. 33.173 + 33.174 +Para estos casos, lo que usted posiblemente desearía serían etiquetas 33.175 +\emph{locales}. Puede crear una etiqueta local con la opción~\hgopt{tag}{-l} 33.176 +de la orden \hgcmd{tag}. Esto guardará la etiqueta en un fichero llamado 33.177 +\sfilename{.hg/localtags}. A diferencia de \sfilename{.hgtags}, 33.178 +\sfilename{.hg/localtags} no está controlado por revisiones. 33.179 +Cualquier etiqueta que usted cree usando \hgopt{tag}{-l} se mantendrá 33.180 +local al repositorio en el que esté trabajando en ese momento. 33.181 + 33.182 +\section{El flujo de cambios---El gran cuadro vs. el pequeño} 33.183 + 33.184 +Retomando lo mencionado en el comienzo de un capítulo, pensemos en el 33.185 +hecho de que un proyecto tiene muchas piezas concurrentes de trabajo 33.186 +en desarrollo al mismo tiempo. 33.187 + 33.188 +Puede haber prisa por una nueva versión ``principal''; una nueva 33.189 +versión con un arreglo de fallo a la última versión; y una versión de 33.190 +``mantenimiento correctivo'' a una versión antigua que ha entrado en 33.191 +modo de mantenimiento. 33.192 + 33.193 +Usualmente la gente se refiere a esas direcciones 33.194 +concurrentes de desarrollo como ``ramas''. Sin embargo, ya hemos visto que 33.195 +en varias ocasiones Mercurial trata a \emph{todo el historial} como 33.196 +una serie de ramas y fusiones. Realmente lo que tenemos aquí es dos 33.197 +ideas que se relacionan periféricamente, pero que en esencia comparten 33.198 +un nombre. 33.199 +\begin{itemize} 33.200 +\item ``El gran cuadro'' Las ramas representan un barrido de la 33.201 + evolución del proyecto; la gente les da nombres y hablan acerca de 33.202 + ellas en sus conversaciones. 33.203 +\item ``El cuadro pequeño'' Las ramas son artefactos de las 33.204 + actividades diarias de desarrollar y fusionar cambios. Exponen la 33.205 + narrativa de cómo se desarrolló el código. 33.206 +\end{itemize} 33.207 + 33.208 +\section{Administrar ramas en repositorios estilo gran cuadro} 33.209 + 33.210 +En Mercurial la forma más sencilla de aislar una rama del ``gran 33.211 +cuadro'' es a través de un repositorio dedicado. Si cuenta con un 33.212 +repositorio compartido existente ---llamémoslo 33.213 +\texttt{myproject}---que alcanzó la etapa ``1.0'', puede comenzar a 33.214 +prepararse para versiones de mantenimiento futuras a partir de la 33.215 +versión~1.0 marcando con una etiqueta la revisión con la cual preparó la versión~1.0. 33.216 +\interaction{branch-repo.tag} 33.217 +Ahora puede clonar un repositorio compartido nuevo 33.218 +\texttt{myproject-1.0.1} con tal etiqueta. 33.219 +\interaction{branch-repo.clone} 33.220 + 33.221 +Posteriormente, si alguien necesita trabajar en la reparación de un 33.222 +fallo debería dirigirse a la liberación de versión~1.0.1 que viene en 33.223 +camino, ellos clonarían el repositorio \texttt{myproject-1.0.1}, 33.224 +harían sus cambios y los empujarían de vuelta. 33.225 +\interaction{branch-repo.bugfix} 33.226 +Mientras tanto, el desarrollo para la siguiente versión mayor puede 33.227 +continuar aislado e incólume, en el repositorio \texttt{myproject}. 33.228 +\interaction{branch-repo.new} 33.229 + 33.230 +\section{No repita trabajo: fusión entre ramas} 33.231 + 33.232 +En muchos casos, cuando tiene un fallo para arreglar en una rama de 33.233 +mantenimiento, es muy probable que el fallo también esté en la rama 33.234 +principal (y posiblemente en otras ramas de mantenimiento 33.235 +también). Solamente un desarrollador extraño desearía corregir el 33.236 +mismo fallo muchas veces, por tanto, veremos varias alternativas con 33.237 +las que Mercurial puede ayudarle a administrar tales arreglos de fallo 33.238 +sin duplicar su trabajo. 33.239 + 33.240 +En el caso más sencillo, basta con jalar los cambios de la rama de 33.241 +mantenimiento a la rama objetivo en su clon local. 33.242 +\interaction{branch-repo.pull} 33.243 +A continuación deberá mezclar las cabezas de las dos ramas, y empujar 33.244 +de nuevo a la rama principal. 33.245 +\interaction{branch-repo.merge} 33.246 + 33.247 +\section{Nombrar ramas dentro de un repositorio} 33.248 + 33.249 +La aproximación correcta en casi todas las oportunidades es aislar las 33.250 +ramas en los repositorios. Es fácil de entender gracias a su 33.251 +simplicidad; y es difícil cometer errores. Hay una relación uno a uno 33.252 +entre las ramas y los directorios con los que está trabajando en su 33.253 +sistema. Esto le permite usar emplear herramientas usuales (que no son 33.254 +conscientes de Mercurial) para trabajar con los ficheros dentro de una 33.255 +rama/repositorio. 33.256 + 33.257 +Si se encuentra más en la categoría ``usuario diestro'' (\emph{y} sus 33.258 +colaboradores también), puede considerar otra alternativa para 33.259 +administrar las ramas. He mencionado con anterioridad la distinción a 33.260 +nivel humano entre las ramas estilo ``cuadro pequeño'' y ``gran 33.261 +cuadro''. Mientras que Mercurial trabaja con muchas ramas del estilo 33.262 +``cuadro pequeño'' en el repositorio todo el tiempo (por ejemplo cuando 33.263 +usted jala cambios, pero antes de fusionarlos), \emph{también} puede 33.264 +trabajar con varias ramas del ``cuadro grande''. 33.265 + 33.266 +El truco para trabajar de esta forma en Mercurial se logra gracias a 33.267 +que puede asignar un \emph{nombre} persistente a una rama. Siempre 33.268 +existe una rama llamada \texttt{default}. Incluso antes de que 33.269 +empiece a nombrar ramas por su cuenta, puede encontrar indicios de la 33.270 +rama \texttt{default} si los busca. 33.271 + 33.272 +Por ejemplo, cuando invoca la orden \hgcmd{commit}, y se lanza su 33.273 +editor para introducir el mensaje de la consignación, busque la línea 33.274 +que contiene el texto ``\texttt{HG: branch default}'' al final. Le 33.275 +está indicando que su consignación ocurrirá en la rama llamada 33.276 +\texttt{default}. 33.277 + 33.278 +Use la orden \hgcmd{branches} para empezar a trabajar con ramas 33.279 +nombradas. Esta orden mostrará las ramas presentes en su repositorio, 33.280 +indicándole qué conjunto de cambios es la punta de cada una. 33.281 +\interaction{branch-named.branches} 33.282 +Dado que todavía no ha creado ramas nombradas, la única que verá será 33.283 +\texttt{default}. 33.284 + 33.285 +Para hallar cuál es la rama ``actual'', invoque la orden 33.286 +\hgcmd{branch}, sin argumento alguno. Le informará en qué rama se 33.287 +encuentra el padre del conjunto de cambios actual. 33.288 +\interaction{branch-named.branch} 33.289 + 33.290 +Para crear una nueva rama, invoque la orden \hgcmd{branch} de 33.291 +nuevo. En esta oportunidad, ofrezca un argumento: el nombre de la rama 33.292 +que desea crear. 33.293 +\interaction{branch-named.create} 33.294 + 33.295 +Después de crear la rama, usted podría desear ver el efecto que tuvo 33.296 +la orden \hgcmd{branch}. ¿Qué reportan las ordenes \hgcmd{status} y 33.297 +\hgcmd{tip}? 33.298 +\interaction{branch-named.status} 33.299 +Nada cambia en el directorio actual, y no se ha añadido nada al 33.300 +historial. Esto sugiere que al ejecutar la orden \hgcmd{branch} no hay 33.301 +un efecto permanente; solamente le indica a que nombre de rama usará 33.302 +la \emph{próxima} vez que consigne un conjunto de cambios. 33.303 + 33.304 +Cuando consigna un cambio, Mercurial almacena el nombre de la rama en 33.305 +la cual consignó. Una vez que haya cambiado de la rama \texttt{default} 33.306 +y haya consignado, verá que el nombre de la nueva rama se mostrará 33.307 +cuando use la orden \hgcmd{log}, \hgcmd{tip}, y otras órdenes que 33.308 +desplieguen la misma clase de información. 33.309 +\interaction{branch-named.commit} 33.310 +Las órdenes del tipo \hgcmd{log} imprimirán el nombre de la rama de 33.311 +cualquier conjunto de cambios que no esté en la rama 33.312 +\texttt{default}. Como resultado, si nunca usa ramas nombradas, nunca 33.313 +verá esta información. 33.314 + 33.315 +Una vez que haya nombrado una rama y consignado un cambio con ese 33.316 +nombre, todas las consignaciones subsecuentes que desciendan de ese 33.317 +cambio heredarán el mismo nombre de rama. Puede cambiar el nombre de 33.318 +una rama en cualquier momento con la orden \hgcmd{branch}. 33.319 +\interaction{branch-named.rebranch} 33.320 +Esto es algo que no hará muy seguido en la práctica, debido que los 33.321 +nombres de las ramas tienden a tener vidas largas. (Esto no es una 33.322 +regla, solamente una observación.) 33.323 + 33.324 +\section{Tratamiento de varias ramas nombradas en un repositorio} 33.325 + 33.326 +Si tiene más de una rama nombrada en un repositorio, Mercurial 33.327 +recordará la rama en la cual está su directorio de trabajo cuando 33.328 +invoque una orden como \hgcmd{update} o \hgcmdargs{pull}{-u}. Se 33.329 +actualizará su directorio de trabajo actual a la punta de esta rama, sin 33.330 +importar cuál sea la punta ``a lo largo del repositorio''. Para 33.331 +actualizar a una revisión que está en una rama con distinto nombre, 33.332 +puede necesitar la opción \hgopt{update}{-C} de \hgcmd{update}. 33.333 + 33.334 +Este comportamiento puede ser sutil, así que veámoslo en acción. Primero, 33.335 +recordemos en qué rama estamos trabajando, y qué ramas están en 33.336 +nuestro repositorio. 33.337 +\interaction{branch-named.parents} 33.338 +Estamos en la rama \texttt{bar}, pero existe otra rama más antigua 33.339 +llamada \hgcmd{foo}. 33.340 + 33.341 +Podemos hacer \hgcmd{update} entre los tipos de las ramas \texttt{foo} 33.342 +y \texttt{bar} sin necesidad de usar la opción \hgopt{update}{-C}, 33.343 +puesto que esto solamente implica ir linealmente hacia adelante y 33.344 +atrás en nuestro historial de cambios. 33.345 +\interaction{branch-named.update-switchy} 33.346 + 33.347 +Si volvemos a la rama \texttt{foo} e invocamos la orden \hgcmd{update}, 33.348 +nos mantendrá en \texttt{foo}, sin movernos a la punta de \texttt{bar}. 33.349 +\interaction{branch-named.update-nothing} 33.350 + 33.351 +Al consignar un cambio a la rama \texttt{foo} se introducirá una nueva 33.352 +cabeza. 33.353 +\interaction{branch-named.foo-commit} 33.354 + 33.355 +\section{Nombres de ramas y fusiones} 33.356 + 33.357 +Posiblemente ha notado que las fusiones en Mercurial no son simétricas. 33.358 +Supongamos que su repositorio tiene dos cabezas, 17 y 23. Si yo invoco 33.359 +\hgcmd{update} a 17 y aplico \hgcmd{merge} a 23, Mercurial almacena 17 33.360 +como el primer padre de la fusión, y 23 como el segundo. Mientras que 33.361 +si hago \hgcmd{update} a 23 y después aplico \hgcmd{merge} con 17, 33.362 +grabará a 23 como el primer padre, y 17 como el segundo. 33.363 + 33.364 +Esto afecta el cómo elige Mercurial el nombre de la rama cuando usted 33.365 +hace la fusión. Después de una fusión, Mercurial mantendrá el nombre de la 33.366 +rama del primer padre cuando consigne el resultado de la fusión. Si 33.367 +el primer nombre de su padre es \texttt{foo}, y fusiona con 33.368 +\texttt{bar}, el nombre de la rama continuará siendo \texttt{foo} 33.369 +después de fusionar. 33.370 + 33.371 +No es inusual que un repositorio contenga varias cabezas, cada una con 33.372 +el mismo nombre de rama. Digamos que estoy trabajando en la rama 33.373 +\texttt{foo}, y usted también. Consignamos cambios distintos; yo jalo 33.374 +sus cambios; Ahora tengo dos cabezas, cada una afirmando estar en la 33.375 +rama \texttt{foo}. El resultado de una fusión será una única cabeza 33.376 +en la rama \texttt{foo} como usted esperaría. 33.377 + 33.378 +Pero si estoy trabajando en la rama \texttt{bar}, y fusiono el trabajo 33.379 +de la rama \texttt{foo}, el resultado permanecerá en la rama 33.380 +\texttt{bar}. 33.381 +\interaction{branch-named.merge} 33.382 + 33.383 +En un ejemplo más concreto, si yo estoy trabajando en la rama 33.384 +\texttt{bleeding-edge}, y deseo traer los arreglos más recientes de la 33.385 +rama \texttt{estable}, Mercurial elegirá el nombre de rama ``correcto'' 33.386 +(\texttt{bleeding-edge}) cuando yo jale una fusión desde \texttt{estable}. 33.387 + 33.388 +\section{Normalmente es útil nombrar ramas} 33.389 + 33.390 +No debería considerar que las ramas nombradas son aplicables 33.391 +únicamente en situaciones con muchas ramas de larga vida cohabitando 33.392 +en un mismo repositorio. Son muy útiles incluso en los casos de 33.393 +una rama por repositorio. 33.394 + 33.395 +En el caso más sencillo, dar un nombre a cada rama ofrece un registro 33.396 +permanente acerca de en qué conjunto de cambios se generó la rama. 33.397 +Esto le ofrece más contexto cuando esté tratando de seguir el 33.398 +historial de un proyecto ramificado de larga vida. 33.399 + 33.400 +Si está trabajando con repositorios compartidos, puede configurar el gancho 33.401 +\hook{pretxnchangegroup} para que cada uno bloquee los cambios con 33.402 +nombres de rama ``incorrectos'' que están por adicionarse. Este 33.403 +provee una defensa sencilla, pero efectiva, para evitar que la gente 33.404 +publique accidentalmente cambios de una rama ``super nueva'' a la rama 33.405 +``estable''. Tal gancho podría verse de la siguiente forma dentro de 33.406 +un repositorio compartido de \hgrc. 33.407 +\begin{codesample2} 33.408 + [hooks] 33.409 + pretxnchangegroup.branch = hg heads --template '{branches} ' | grep mybranch 33.410 +\end{codesample2} 33.411 + 33.412 +%%% Local Variables: 33.413 +%%% mode: latex 33.414 +%%% TeX-master: "00book" 33.415 +%%% End:
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 34.2 +++ b/es/cmdref.py Thu Jan 29 22:00:07 2009 -0800 34.3 @@ -0,0 +1,1 @@ 34.4 +../en/cmdref.py 34.5 \ No newline at end of file
35.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 35.2 +++ b/es/cmdref.tex Thu Jan 29 22:00:07 2009 -0800 35.3 @@ -0,0 +1,186 @@ 35.4 +\chapter{Referencia de Órdenes} 35.5 +\label{cmdref} 35.6 + 35.7 +\cmdref{add}{Añade ficheros en la próxima consignación} 35.8 +\optref{add}{I}{include} 35.9 +\optref{add}{X}{exclude} 35.10 +\optref{add}{n}{dry-run} 35.11 + 35.12 +\cmdref{diff}{imprime los cambios en el historial o el directorio actual} 35.13 + 35.14 +Mostrar las diferencias entre revisiones para ficheros especificados o 35.15 +directorios, con el formato unificado diff. Si desea ver una 35.16 +descripción del formato unificado diff, ver la sección~\ref{sec:mq:patch}. 35.17 + 35.18 +De forma predeterminada, esta orden no imprime las diferencias para 35.19 +los ficheros binarios que Mercurial esté siguiendo. Para controlar 35.20 +este comportamiento, vea las opciones \hgopt{diff}{-a} y 35.21 +\hgopt{diff}{--git}. 35.22 + 35.23 +\subsection{Options} 35.24 + 35.25 +\loptref{diff}{nodates} 35.26 + 35.27 +Omite la fecha y hora cuando se muestran los encabezados de las 35.28 +diferencias. 35.29 + 35.30 +\optref{diff}{B}{ignore-blank-lines} 35.31 + 35.32 +No imprime los cambios que solamente insertan o eliminan líneas en 35.33 +blanco. Una línea que contiene espacios en blanco no se considera 35.34 +como una línea en blanco. 35.35 + 35.36 +\optref{diff}{I}{include} 35.37 + 35.38 +Incluye ficheros y directorios cuyos nombres coinciden con los 35.39 +patrones elegidos. 35.40 + 35.41 +\optref{diff}{X}{exclude} 35.42 + 35.43 +Excluye los ficheros y directorios cuyos nombres coinciden con los 35.44 +patrones elegidos. 35.45 + 35.46 +\optref{diff}{a}{text} 35.47 + 35.48 +Si no especifica esta opción, \hgcmd{diff} no mostrará las diferencias 35.49 +de los ficheros que detecte como binarios. Al especificar \hgopt{diff}{-a} 35.50 +se forza a \hgcmd{diff} a tratar los ficheros como texto, y generar 35.51 +diferencias para todos. 35.52 + 35.53 +Esta opción es útil para los ficherso que son ``texto en mayor 35.54 +medida'' pero que tienen caracteres NUL. Si lo usa en ficheros que 35.55 +contienen muchos datos binarios, la salida será incomprensible. 35.56 + 35.57 +\optref{diff}{b}{ignore-space-change} 35.58 + 35.59 +No imprime si el único cambio que en la línea es la cantidad de 35.60 +espacio en blanco. 35.61 + 35.62 +\optref{diff}{g}{git} 35.63 + 35.64 +Mostrar diferencias compatibles con \command{git}. XXX reference a format 35.65 +description. 35.66 + 35.67 +\optref{diff}{p}{show-function} 35.68 + 35.69 +Mostrar el nombre de la función que contiene el código en una porción 35.70 +del encabzado usando una heurística simple. Esta funcionalidad se 35.71 +habilita de forma predeterminada, así que la opción \hgopt{diff}{-p} 35.72 +no tiene efectos a menos que cambie el valor de 35.73 +\rcitem{diff}{showfunc} en la configuración, como en el ejemplo 35.74 +siguiente. 35.75 +\interaction{cmdref.diff-p} 35.76 + 35.77 +\optref{diff}{r}{rev} 35.78 + 35.79 +Especifique una o más revisiones para comparar. La orden \hgcmd{diff} 35.80 +acepta hasta dos opciones \hgopt{diff}{-r} para especificar las 35.81 +revisiones a comparar. 35.82 + 35.83 +\begin{enumerate} 35.84 +\setcounter{enumi}{0} 35.85 +\item Despliega las diferencias entre la revisión padre y del directorio 35.86 + de trabajo. 35.87 +\item Despliega las diferencias entre el conjunto de cambios 35.88 + especificados y el directorio de trabajo. 35.89 +\item Despliega las diferencias entre dos conjuntos de cambios 35.90 + especificados. 35.91 +\end{enumerate} 35.92 + 35.93 +Puede especificar dos revisiones usando o bien sea las opciones 35.94 +\hgopt{diff}{-r} o la notación de rango. Por ejemplo, las dos 35.95 +especificaciones de revisiones a continuación son equivalentes: 35.96 +\begin{codesample2} 35.97 + hg diff -r 10 -r 20 35.98 + hg diff -r10:20 35.99 +\end{codesample2} 35.100 + 35.101 +Cuando especifica dos revisiones, esto tiene significado para 35.102 +Mercurial. Esto significa que \hgcmdargs{diff}{-r10:20} producirá un 35.103 +diff que transformará los ficheros desde los contenidos en la revisión 35.104 +10 a los contenidos de la revisión 20, mientras que 35.105 +\hgcmdargs{diff}{-r20:10} significa lo opuesto: el diff que 35.106 +transformaría los contenidos de los ficheros de la revisión 20 a los 35.107 +contenidos de la revisión 10. No puede invertir el orden de esta 35.108 +forma si está haciendo un diff frente al directorio de trabajo. 35.109 + 35.110 +\optref{diff}{w}{ignore-all-space} 35.111 + 35.112 +\cmdref{version}{imprime la información de versión y derechos de reproducción} 35.113 + 35.114 +Esta orden despliega la versión de Mercurial que está usando, y su 35.115 +nota de derechos de reproducción. Hay cuatro clases de cadenas de 35.116 +versión posibles: 35.117 +\begin{itemize} 35.118 +\item La cadena ``\texttt{unknown}''. Esta versión de Mercurial no fue 35.119 + construida en un repositorio de Mercurial, y no puede determinar su 35.120 + propia versión. 35.121 +\item Una cadena numérica corta, tal como ``\texttt{1.1}''. Esta es 35.122 + una construcción de una versión de Mercurial que se identifica con 35.123 + una etiqueta específica en el repositorio en el cual fue 35.124 + armada (Esto no significa necesariamente que está ejecutando una 35.125 + versión oficial; alguien pudo haber añadido tal etiqueta a cualquier 35.126 + versión del repositorio en el cual armaron Mercurial). 35.127 +\item Una cadena hexadecimal, tal como ``\texttt{875489e31abe}''. 35.128 + Esta es una construcción de una revisión dada de Mercurial. 35.129 +\item Una cadena hexadecimal seguida por una fecha, tal como 35.130 + ``\texttt{875489e31abe+20070205}''. Esta construcción de la 35.131 + revisión de Mercurial fue la construcción de un repositorio que tuvo 35.132 + cambios locales que no han sido consignados. 35.133 +\end{itemize} 35.134 + 35.135 +\subsection{Consejos y trucos} 35.136 + 35.137 +\subsubsection{¿Por qué difieren los resultados de \hgcmd{diff} y 35.138 + \hgcmd{status}?} 35.139 +\label{cmdref:diff-vs-status} 35.140 + 35.141 +Cuando ejecuta la orden \hgcmd{status}, verá una lista de ficheros 35.142 +para los cuales Mercurial almacenará cambios la próxima vez que 35.143 +consigne. Si ejecuta la orden \hgcmd{diff}, verá que imprime 35.144 +diferencias solamente para un \emph{subconjunto} de los ficheros que 35.145 +\hgcmd{status} liste. Hay dos posibles razones para este comportamiento: 35.146 + 35.147 +La primera es que \hgcmd{status} imprime cierta clase de 35.148 +modificaciones que \hgcmd{diff} no despliega normalmente. La orden 35.149 +\hgcmd{diff} usualmente despliega diferencias unificadas, las cuales 35.150 +no tienen la habilidad de representar algunos cambios que Mercurial 35.151 +puede seguir. Lo más notable es que las diferencias tradicionales no 35.152 +pueden representar un cambio acerca de la ejecutabilidad de un 35.153 +fichero, pero Mercurial sí almacena esta información. 35.154 + 35.155 +Si usa la opción \hgopt{diff}{--git} de \hgcmd{diff}, mostrará 35.156 +diferencias compatibles con \command{git} que \emph{pueden} desplegar 35.157 +esta información adicional. 35.158 + 35.159 +La segunda razón posible para que \hgcmd{diff} esté imprimiendo 35.160 +diferencias para un subconjunto de ficheros de lo que muestra 35.161 +\hgcmd{status} es que si usted le invoca sin argumento alguno, 35.162 +\hgcmd{diff} imprime diferencias frente al primer padre del directorio 35.163 +de trabajo. Si ha ejecutado \hgcmd{merge} para fusionar dos conjuntos 35.164 +de cambios, pero no ha consignado aún los resultados de la fusión, su 35.165 +directorio de trabajo tiene dos padres (use \hgcmd{parents} para 35.166 +verlos). Mientras que \hgcmd{status} imprime modificaciones relativas 35.167 +a \emph{ambos} padres después de una fusión que no se ha consignado, 35.168 +\hgcmd{diff} opera aún relativo solamente al primer padre. Puede 35.169 +lograr que imprima las diferencias relativas al segundo padre 35.170 +especificando tal padre con la opción \hgopt{diff}{-r}. No hay forma 35.171 +de hacer que imprima las diferencias relativas a los dos padres. 35.172 + 35.173 +\subsubsection{Generar diferencias seguras en binarios} 35.174 + 35.175 +Si usa la opción \hgopt{diff}{-a} para forzar que Mercurial imprima 35.176 +las diferencias de los ficheros que so o bien ``casi completamente 35.177 +texto'' o contienen muchos datos binarios, tales diferencias no pueden 35.178 +aplicarse subsecuentemente a la orden \hgcmd{import} de Mercurial o a 35.179 +la orden \command{patch} del sistema. 35.180 + 35.181 +Si desea generar una diferencia de un fichero binario que es seguro 35.182 +para usarlo como entrada a la orden \hgcmd{import}, use la opción 35.183 +\hgcmd{diff}{--git} cuando genere el parche. La orden \command{patch} 35.184 +del sistema no puede tratar con parches binarios. 35.185 + 35.186 +%%% Local Variables: 35.187 +%%% mode: latex 35.188 +%%% TeX-master: "00book" 35.189 +%%% End:
36.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 36.2 +++ b/es/collab.tex Thu Jan 29 22:00:07 2009 -0800 36.3 @@ -0,0 +1,1059 @@ 36.4 +\chapter{Colaborar con otros} 36.5 +\label{cha:collab} 36.6 + 36.7 +Debido a su naturaleza descentralizada, Mercurial no impone política 36.8 +alguna de cómo deben trabajar los grupos de personas. Sin embargo, si 36.9 +usted es nuevo al control distribuido de versiones, es bueno tener 36.10 +herramientas y ejemplos a la mano al pensar en posibles modelos de 36.11 +flujo de trabajo. 36.12 + 36.13 +\section{La interfaz web de Mercurial} 36.14 + 36.15 +Mercurial tiene una poderosa interfaz web que provee bastantes 36.16 +capacidades útiles. 36.17 + 36.18 +Para uso interactivo, la interfaz le permite visualizar uno o varios 36.19 +repositorios. Puede ver el historial de un repositorio, examinar cada 36.20 +cambio (comentarios y diferencias), y ver los contenidos de cada 36.21 +directorio y fichero. 36.22 + 36.23 +Adicionalmente la interfaz provee notificaciones RSS de los cambios de los 36.24 +repositorios. Que le permite ``subscribirse''a un repositorio usando 36.25 +su herramienta de lectura de notificaciones favorita, y ser notificado 36.26 +automáticamente de la actividad en el repositorio tan pronto como 36.27 +sucede. Me gusta mucho más este modelo que el estar suscrito a una 36.28 +lista de correo a la cual se envían las notificaciones, dado que no 36.29 +requiere configuración adicional de parte de quien sea que está 36.30 +administrando el repositorio. 36.31 + 36.32 +La interfaz web también permite clonar repositorios a los usuarios 36.33 +remotos, jalar cambios, y (cuando el servidor está configurado para 36.34 +permitirlo) publicar cambios en el mismo. El protocolo de entunelamiento 36.35 +de Mercurial comprime datos agresivamente, de forma que trabaja 36.36 +eficientemente incluso con conexiones de red con poco ancho de banda. 36.37 + 36.38 +La forma más sencilla de iniciarse con la interfaz web es usar su 36.39 +navegador para visitar un repositorio existente, como por ejemplo el 36.40 +repositorio principal de Mercurial \url{http://www.selenic.com/repo/hg?style=gitweb}. 36.41 + 36.42 +Si está interesado en proveer una interfaz web a sus propios 36.43 +repositorios, Mercurial provee dos formas de hacerlo. La primera es 36.44 +usando la orden \hgcmd{serve}, que está enfocada a servir ``de forma 36.45 +liviana'' y por intervalos cortos. Para más detalles de cómo usar 36.46 +esta orden vea la sección~\ref{sec:collab:serve} más adelante. Si 36.47 +tiene un repositorio que desea hacer permanente, Mercurial tiene 36.48 +soporte embebido del \command{ssh} para publicar cambios con seguridad 36.49 +al repositorio central, como se documenta en la 36.50 +sección~\ref{sec:collab:ssh}. Es muy usual que se publique una copia 36.51 +de sólo lectura en el repositorio que está corriendo sobre HTTP usando 36.52 +CGI, como en la sección~\ref{sec:collab:cgi}. Publicar sobre HTTP 36.53 +satisface las necesidades de la gente que no tiene permisos de 36.54 +publicación y de aquellos que quieren usar navegadores web para 36.55 +visualizar el historial del repositorio. 36.56 + 36.57 +\subsection{Trabajo con muchas ramas} 36.58 + 36.59 +Los proyectos de cierta talla tienden naturalmente a progresar de 36.60 +forma simultánea en varios frentes. En el caso del software, es común 36.61 +que un proyecto tenga versiones periódicas oficiales. Una versión 36.62 +puede entrar a ``modo mantenimiento'' por un tiempo después de su 36.63 +primera publicación; las versiones de mantenimiento tienden a contener 36.64 +solamente arreglos de fallos, pero no nuevas características. En 36.65 +paralelo con las versiones de mantenimiento puede haber una o muchas 36.66 +versiones futuras pueden estar en desarrollo. La gente usa normalmente 36.67 +la palabra ``rama'' para referirse a una de las direcciones 36.68 +ligeramente distintas en las cuales procede el desarrollo. 36.69 + 36.70 +Mercurial está especialmente preparado para administrar un buen número 36.71 +de ramas simultáneas pero no idénticas. Cada ``dirección de 36.72 +desarrollo'' puede vivir en su propio repositorio central, y puede 36.73 +mezclar los cambios de una a otra de acuerdo con las necesidades. Dado 36.74 +que los repositorios son independientes, uno del otro, los cambios 36.75 +inestables de una rama de desarrollo nunca afectarán una rama estable 36.76 +a menos que alguien explícitamente mezcle los cambios. 36.77 + 36.78 +A continuación un ejemplo de cómo podría hacerse esto en la 36.79 +práctica. Digamos que tiene una ``rama principal'' en un servidor 36.80 +central. 36.81 +\interaction{branching.init} 36.82 +Alguien lo clona, hace cambios locales, los prueba, y los publica allí 36.83 +mismo. 36.84 + 36.85 +Una vez que la rama principal alcanza una estado de versión se puede 36.86 +usar la orden \hgcmd{tag} para dar un nombre permanente a la revisión. 36.87 +\interaction{branching.tag} 36.88 +Digamos que en la rama principal ocurre más desarrollo. 36.89 +\interaction{branching.main} 36.90 +Cuando se usa la etiqueta con que se identificó la versión, la gente 36.91 +puede clonar el repositorio en cualquier momento en el futuro 36.92 +empleando \hgcmd{update} para obtener una copia del directorio de 36.93 +trabajo exacta como cuando se creó la etiqueta de la revisión que se 36.94 +consignó. 36.95 +\interaction{branching.update} 36.96 + 36.97 +Adicionalmente, justo después de que la rama principal se etiquete, 36.98 +alguien puede clonarla en el servidor a una nueva rama ``estable'', 36.99 +también en el servidor. 36.100 +\interaction{branching.clone} 36.101 + 36.102 +Alguien que requiera hacer un cambio en la rama estable puede clonar 36.103 +\emph{ese} repositorio, hacer sus cambios, consignar y publicarlos 36.104 +posteriormente al inicial. 36.105 +\interaction{branching.stable} 36.106 +Puesto que los repositorios de Mercurial son independientes, y que 36.107 +Mercurial no mueve los cambios de un lado a otro automáticamente, las 36.108 +ramas estable y principal están \emph{aisladas} la una de la otra. 36.109 +Los cambios que haga en la rama principal no ``se filtran'' a la rama 36.110 +estable o vice versa. 36.111 + 36.112 +Es usual que los arreglos de fallos de la rama estable deban hacerse 36.113 +aparecer en la rama principal también. En lugar de reescribir el 36.114 +arreglo del fallo en la rama principal, puede jalar y mezclar los 36.115 +cambios de la rama estable a la principal, Mercurial traerá tales 36.116 +arreglos por usted. 36.117 +\interaction{branching.merge} 36.118 +La rama principal contendrá aún los cambios que no están en la 36.119 +estable y contendrá además todos los arreglos de fallos de la rama 36.120 +estable. La rama estable permanece incólume a tales cambios. 36.121 + 36.122 +\subsection{Ramas de Características} 36.123 + 36.124 +En proyectos grandes, una forma efectiva de administrar los cambios es 36.125 +dividir el equipo en grupos más pequeños. Cada grupo tiene una rama 36.126 +compartida, clonada de una rama ``principal'' que conforma el proyecto 36.127 +completo. Aquellos que trabajan en ramas individuales típicamente 36.128 +están aislados de los desarrollos de otras ramas. 36.129 + 36.130 +\begin{figure}[ht] 36.131 + \centering 36.132 + \grafix{feature-branches} 36.133 + \caption{Ramas de Características} 36.134 + \label{fig:collab:feature-branches} 36.135 +\end{figure} 36.136 + 36.137 +Cuando una rama particular alcanza un estado deseado, alguien del 36.138 +equipo de características jala y fusiona de la rama principal hacia 36.139 +la rama de características y publica posteriormente a la rama principal. 36.140 + 36.141 +\subsection{El tren de publicación} 36.142 + 36.143 +Algunos proyectos se organizan al estilo``tren'': Una versión se 36.144 +planifica para ser liberada cada cierto tiempo, y las características 36.145 +que estén listas cuando ha llegado el momento ``tren'', se incorporan. 36.146 + 36.147 +Este modelo tiene cierta similitud a las ramas de características. La 36.148 +diferencia es que cuando una característica pierde el tren, alguien en 36.149 +el equipo de características jala y fusiona los cambios que se fueron 36.150 +en la versión liberada hacia la rama de característica, y el trabajo 36.151 +continúa sobre lo fusionado para que la característica logre estar en 36.152 +la próxima versión. 36.153 + 36.154 +\subsection{El modelo del kernel linux} 36.155 + 36.156 +El desarrollo del Kernel Linux tiene una estructura jerárquica 36.157 +bastante horizontal, rodeada de una nube de caos aparente. Dado que la 36.158 +mayoría de desarrolladores usan \command{git}, una herramienta distribuida 36.159 +de control de versiones con capacidades similares a Mercurial, resulta 36.160 +de utilidad describir la forma en que el trabajo fluye en tal 36.161 +ambiente; si le gustan las ideas, la aproximación se traduce bien 36.162 +entre Git y Mercurial. 36.163 + 36.164 +En el centro de la comunidad está Linus Torvalds, el creador de Linux. 36.165 +Él publica un único repositorio que es considerado el árbol 36.166 +``oficial'' actual por la comunidad completa de 36.167 +desarrolladores. Cualquiera puede clonar el árbol de Linus, pero él es 36.168 +muy selectivo acerca de los árboles de los cuales jala. 36.169 + 36.170 +Linus tiene varios ``lugartenientes confiables''. Como regla, él jala 36.171 +todos los cambios que ellos publican, en la mayoría de los casos sin 36.172 +siquiera revisarlos. Algunos de sus lugartenientes generalmente 36.173 +aceptan ser los ``mantenedores'', responsables de subsistemas 36.174 +específicos dentro del kernel. Si un hacker cualquiera desea hacer un 36.175 +cambio a un subsistema y busca que termine en el árbol de Linus, debe 36.176 +encontrar quién es el mantenedor del subsistema y solicitarle que 36.177 +tenga en cuenta su cambio. Si el mantenedor revisa los cambios y está 36.178 +de acuerdo en tomarlos, estos pasarán al árbol de Linus de acuerdo a 36.179 +lo expuesto. 36.180 + 36.181 +Cada lugarteniente tiene su forma particular de revisar, aceptar y 36.182 +publicar los cambios; y para decidir cuando hacerlos presentes a 36.183 +Linus. Adicionalmente existen varias ramas conocidas que mucha gente 36.184 +usa para propósitos distintos. Por ejemplo, pocas personas mantienen 36.185 +repositorios ``estables'' de versiones anteriores del kernel, a los 36.186 +cuales aplican arreglos de fallos críticos necesarios. Algunos 36.187 +mantenedores publican varios árboles: uno para cambios 36.188 +experimentales; uno para cambios que van a ofrecer al mantenedor 36.189 +principal; y así sucesivamente. Otros publican un solo árbol. 36.190 + 36.191 +Este modelo tiene dos características notables. La primera es que son 36.192 +de ``jalar exclusivamente''. Usted debe solicitar, convencer o 36.193 +incluso rogar a otro desarrollador para que tome sus cambios, porque 36.194 +casi no hay árboles en los cuales más de una persona pueda publicar, y 36.195 +no hay forma de publicar cambios en un árbol que otra persona controla. 36.196 + 36.197 +El segundo está basado en reputación y meritocracia. Si usted es un 36.198 +desconocido, Linus probablemente ignorará sus cambios, sin siquiera 36.199 +responderle. Pero un mantenedor de un subsistema probablemente los 36.200 +revisara, y los acogerá en caso de que aprueben su criterio de 36.201 +aplicabilidad. A medida que usted ofrezca ``mejores'' cambios a un 36.202 +mantenedor, habrá más posibilidad de que se confíe en su juicio y se 36.203 +acepten los cambios. Si usted es reconocido y mantiene una rama 36.204 +durante bastante tiempo para algo que Linus no ha aceptado, personas 36.205 +con intereses similares pueden jalar sus cambios regularmente para 36.206 +estar al día con su trabajo. 36.207 + 36.208 +La reputación y meritocracia no necesariamente es transversal entre 36.209 +``personas'' de diferentes subsistemas. Si usted es respetado pero es 36.210 +un hacker en almacenamiento y trata de arreglar un fallo de redes, 36.211 +tal cambio puede recibir un nivel de escrutinio de un mantenedor de 36.212 +redes comparable con el que se le haría a un completo extraño. 36.213 + 36.214 +Personas que vienen de proyectos con un ordenamiento distinto, sienten 36.215 +que el proceso comparativamente caótico del Kernel Linux es 36.216 +completamente lunático. Es objeto de los caprichos individuales; la 36.217 +gente desecha cambios cuando lo desean; y la fase de desarrollo es 36.218 +alucinante. A pesar de eso Linux es una pieza de software exitosa y 36.219 +bien reconocida. 36.220 + 36.221 +\subsection{Solamente jalar frente a colaboración pública} 36.222 + 36.223 +Una fuente perpetua de discusiones en la comunidad de código abierto 36.224 +yace en el modelo de desarrollo en el cual la gente solamente jala 36.225 +cambios de otros ``es mejor que'' uno en el cual muchas personas 36.226 +pueden publicar cambios a un repositorio compartido. 36.227 + 36.228 +Típicamente los partidarios del modelo de publicar usan las herramientas 36.229 +que se apegan a este modelo. Si usted usa una herramienta 36.230 +centralizada de control de versiones como Subversion, no hay forma de 36.231 +elegir qué modelo va a usar: La herramienta le ofrece publicación 36.232 +compartida, y si desea hacer cualquier otra cosa, va a tener que 36.233 +aplicar una aproximación artificial (tal como aplicar parches a mano). 36.234 + 36.235 +Una buena herramienta distribuida de control de versiones, tal como 36.236 +Mercurial soportará los dos modelos. Usted y sus colaboradores 36.237 +pueden estructurar cómo trabajarán juntos basados en sus propias 36.238 +necesidades y preferencias, sin depender de las peripecias que la 36.239 +herramienta les obligue a hacer. 36.240 + 36.241 +\subsection{Cuando la colaboración encuentra la administración ramificada} 36.242 + 36.243 +Una vez que usted y su equipo configurar algunos repositorios 36.244 +compartidos y comienzan a propagar cambios entre sus repositorios 36.245 +locales y compartidos, comenzará a encarar un reto relacionado, pero 36.246 +un poco distinto: Administrar las direcciones en las cuales su equipo 36.247 +puede moverse. A pesar de que está íntimamente ligado acerca de cómo 36.248 +interactúa su equipo, es lo suficientemente denso para ameritar un 36.249 +tratamiento en el capítulo~\ref{chap:branch}. 36.250 + 36.251 +\section{Aspectos técnicos de la colaboración} 36.252 + 36.253 +Lo que resta del capítulo lo dedicamos a las cuestiones de servir 36.254 +datos a sus colaboradores. 36.255 + 36.256 +\section{Compartir informalmente con \hgcmd{serve}} 36.257 +\label{sec:collab:serve} 36.258 + 36.259 +La orden \hgcmd{serve} de Mercurial satisface de forma espectacular 36.260 +las necesidades de un grupo pequeño, acoplado y de corto 36.261 +tiempo. Se constituye en una demostración de cómo se siente usar los 36.262 +comandos usando la red. 36.263 + 36.264 +Ejecute \hgcmd{serve} dentro de un repositorio, y en pocos segundos 36.265 +iniciará un servidor HTTP especializado; aceptará conexiones desde 36.266 +cualquier cliente y servirá datos de este repositorio mientrs lo 36.267 +mantenga funcionando. Todo el que sepa el URL del servidor que ha 36.268 +iniciado, y que puede comunicarse con su computador por la red, puede 36.269 +usar un navegador web o Mercurial para leer datos del repositorio. Un 36.270 +URL para una instancia de \hgcmd{serve} ejecutándose en un portátil 36.271 +debería lucir algo \Verb|http://my-laptop.local:8000/|. 36.272 + 36.273 +La orden \hgcmd{serve} \emph{no} es un servidor web de propósito 36.274 +general. Solamente puede hacer dos cosas: 36.275 +\begin{itemize} 36.276 +\item Permitir que se pueda visualizar el historial del repositorio que 36.277 + está sirviendo desde navegadores web. 36.278 +\item Hablar el protocolo de conexión de Mercurial para que puedan hacer 36.279 + \hgcmd{clone} o \hgcmd{pull} (jalar) cambios de tal repositorio. 36.280 +\end{itemize} 36.281 +En particular, \hgcmd{serve} no permitirá que los usuarios remotos 36.282 +puedan \emph{modificar} su repositorio. Es de tipo solo lectura. 36.283 + 36.284 +Si está comenzando con Mercurial, no hay nada que le impida usar 36.285 +\hgcmd{serve} para servir un repositorio en su propio computador, y 36.286 +usar posteriormente órdenes como \hgcmd{clone}, \hgcmd{incoming}, para 36.287 +comunicarse con el servidor como si el repositorio estuviera alojado 36.288 +remotamente. Lo que además puede ayudarle a adecuarse rápidamente para 36.289 +usar comandos en repositorios alojados en la red. 36.290 + 36.291 +\subsection{Cuestiones adicionales para tener en cuenta} 36.292 + 36.293 +Dado que permite lectura sin autenticación a todos sus clientes, 36.294 +debería usar \hgcmd{serve} exclusivamente en ambientes en los cuáles 36.295 +no tenga problema en que otros vean, o en los cuales tenga control 36.296 +completo acerca de quien puede acceder a su red y jalar cambios de su 36.297 +repositorio. 36.298 + 36.299 +La orden \hgcmd{serve} no tiene conocimiento acerca de programas 36.300 +cortafuegos que puedan estar instalados en su sistema o en su red. No 36.301 +puede detectar o controlar sus cortafuegos. Si otras personas no 36.302 +pueden acceder a su instancia \hgcmd{serve}, lo siguiente que debería hacer 36.303 +(\emph{después} de asegurarse que tienen el URL correcto) es verificar 36.304 +su configuración de cortafuegos. 36.305 + 36.306 +De forma predeterminada, \hgcmd{serve} escucha conexiones entrantes en 36.307 +el puerto~8000. Si otro proceso está escuchando en tal puerto, usted 36.308 +podrá especificar un puerto distinto para escuchar con la opción 36.309 +\hgopt{serve}{-p}. 36.310 + 36.311 +Normalmente, cuando se inicia \hgcmd{serve}, no imprime nada, lo cual 36.312 +puede ser desconcertante. Si desea confirmar que en efecto está 36.313 +ejecutándose correctamente, y darse cuenta qué URL debería enviar a 36.314 +sus colaboradores, inícielo con la opción \hggopt{-v}. 36.315 + 36.316 +\section{Uso del protocolo Secure Shell (ssh)} 36.317 +\label{sec:collab:ssh} 36.318 + 36.319 +Usted puede publicar y jalar cambios en la red de forma segura usando 36.320 +el protocolo Secure Shell (\texttt{ssh}). Para usarlo satisfactoriamente, 36.321 +tendrá que hacer algo de configuración a nivel de cliente o el 36.322 +servidor. 36.323 + 36.324 +Si no está familiarizado con ssh, es un protocolo de red que le permite 36.325 +comunicarse con seguridad con otro computador. Para usarlo con 36.326 +Mercurial, estará estableciendo una o más cuentas de usuario en un 36.327 +servidor de forma tal que los usuarios remotos puedan entrar y 36.328 +ejecutar órdenes. 36.329 + 36.330 +(Si ssh le \emph{es} familiar, encontrará probablemente elemental una 36.331 +porción del material a continuación.) 36.332 + 36.333 +\subsection{Cómo leer y escribir URLs de ssh} 36.334 + 36.335 +Los URLs de ssh tienden a lucir de la siguiente forma: 36.336 +\begin{codesample2} 36.337 + ssh://bos@hg.serpentine.com:22/hg/hgbook 36.338 +\end{codesample2} 36.339 +\begin{enumerate} 36.340 +\item La parte ``\texttt{ssh://}'' indica a Mercurial que use el 36.341 + protocolo ssh. 36.342 +\item El componente ``\texttt{bos@}'' indica el nombre del usuario que 36.343 + está entrando al servidor. Puede omitirlo si el usuario remoto 36.344 + coincide con el usuario local. 36.345 +\item ``\texttt{hg.serpentine.com}'' es el nombre del servidor al cual 36.346 + se desea entrar. 36.347 +\item El ``:22'' identifica el número del puerto en el servidor al cual 36.348 + se conectará. El predeterminado es el~22, así que solamente 36.349 + necesitará especificar esa porción si \emph{no} está usando el 36.350 + puerto~22. 36.351 +\item La última porción del URL es la ruta local al repositorio en el 36.352 + servidor. 36.353 +\end{enumerate} 36.354 + 36.355 +El componente de la ruta del URL para ssh es una fuente de confusión, 36.356 +puesto que no hay una forma estándar para que las herramientas puedan 36.357 +interpretarlo. Algunos programas se comportan de manera distinta a 36.358 +otros cuando manipulan estas rutas. No es la situación ideal, pero 36.359 +es muy poco probable que vaya a cambiar. Por favor lea los párrafos 36.360 +siguientes cuidadosamente. 36.361 + 36.362 +Mercurial trata la ruta al repositorio en el servidor como relativo al 36.363 +directorio personal del usuario remoto. Por ejemplo, si el usuario 36.364 +\texttt{foo} en el servidor tiene el directorio casa 36.365 +\dirname{/home/foo}, 36.366 +entonces un URL ssh que contenga en su ruta a \dirname{bar} 36.367 +\emph{realmente} se refiere al directorio \dirname{/home/foo/bar}. 36.368 + 36.369 +Si desea especificar una ruta relativa a otro directorio de usuario, 36.370 +puede usar una ruta que comience con un caracter tildado, seguido del 36.371 +nombre del usuario (llamémosle \texttt{otrousuario}, así 36.372 +\begin{codesample2} 36.373 + ssh://server/~otrousuario/hg/repo 36.374 +\end{codesample2} 36.375 + 36.376 +Y si realmente desea especifica una ruta \emph{absoluta} en el 36.377 +servidor, comience con el componente de la ruta con dos barras como 36.378 +en el siguiente ejemplo: 36.379 +\begin{codesample2} 36.380 + ssh://server//absolute/path 36.381 +\end{codesample2} 36.382 + 36.383 +\subsection{Encontrar un cliente ssh para su sistema} 36.384 + 36.385 +Casi todos los sistemas tipo Unix vienen con OpenSSH preinstalado. Si 36.386 +usted está usando un sistema de estos, ejecute \Verb|which ssh| para 36.387 +identificar dónde está instalada la orden \command{ssh} (usualmente 36.388 +estará en \dirname{/usr/bin}). Si por casualidad no está presente, 36.389 +vea la documentación de sus sistema para lograr instalarlo. 36.390 + 36.391 +En Windows, tendrá que escoger primero un cliente adecuado para 36.392 +descargarlo. Hay dos alternativas: 36.393 +\begin{itemize} 36.394 +\item El excelente paquete PuTTY~\cite{web:putty} de Simon Tatham, que 36.395 + ofrece un suite completo de órdenes de cliente ssh. 36.396 +\item Si tiene alta tolerancia al dolor, puede usar el porte de Cygwin 36.397 + para OpenSSH. 36.398 +\end{itemize} 36.399 +En cualquier caso, tendrá que editar su fichero \hgini\ para indicarle 36.400 +a Mercurial dónde encontrar la orden real del cliente. Por ejemplo, si 36.401 +está usando PuTTY, tendrá que usar la orden \command{plink} como un 36.402 +cliente de línea de órdenes. 36.403 +\begin{codesample2} 36.404 + [ui] 36.405 + ssh = C:/ruta/a/plink.exe -ssh -i "C:/ruta/a/mi/llave/privada" 36.406 +\end{codesample2} 36.407 + 36.408 +\begin{note} 36.409 + La ruta a \command{plink} no debería contener espacios o caracteres 36.410 + en blanco, o Mercurial no podrá encontrarlo correctamente (por lo 36.411 + tanto, probablemente no sería buena idea colocarlo en 36.412 + \dirname{C:\\Program Files} 36.413 +\end{note} 36.414 + 36.415 +\subsection{Generar un par de llaves} 36.416 + 36.417 +Para evitar la necesidad de teclear una clave de forma repetitiva cada 36.418 +vez que necesita usar el cliente, recomiendo generar un par de llaves. 36.419 +En un sistema tipo Unix, la orden \command{ssh-keygen} también se 36.420 +comportará bien. En Windows, si está usando PuTTY, la orden 36.421 +\command{puttygen} es la que necesitará. 36.422 + 36.423 +Cuando genera un par de llaves, se aconseja \emph{comedidamente} 36.424 +protegerlas con una frase de clave. (La única oportunidad en la cual 36.425 +usted querría identificarse una única vez, es cuando está usando 36.426 +el protocolo ssh para tareas automatizadas en una red segura.) 36.427 + 36.428 +No basta con generar un par de llaves. Se requiere adicionar una llave 36.429 +pública al conjunto de llaves autorizadas para todos los usuarios 36.430 +remotos que se vayan a autenticar. Para aquellos servidores que usen 36.431 +OpenSSH (la gran mayoría), significará añadir la llave pública a la 36.432 +lista en el fichero llamado \sfilename{authorized\_keys} en su 36.433 +directorio \sdirname{.ssh}. 36.434 + 36.435 +En sistemas tipo Unix, su llave pública tendrá la extensión 36.436 +\filename{.pub}. Si usa \command{puttygen} en Windows, puede 36.437 +guardar la llave pública en un fichero de su elección, o pegarla desde 36.438 +la ventana en la cual se despliega directamente en el fichero 36.439 +\sfilename{authorized\_keys}. 36.440 + 36.441 +\subsection{Uso de un agente de autenticación} 36.442 + 36.443 +Un agente de autenticación es un demonio que almacena frases clave en 36.444 +memoria (olvidará las frases clave si sale y vuelve a entrar). Un cliente 36.445 +ssh notará si está corriendo, y solicitará una frase clave. Si no hay 36.446 +un agente de autenticación corriendo, o el agente no almacena la frase 36.447 +clave necesaria, tendrá que teclear su frase clave cada vez que 36.448 +Mercurial intente comunicarse con un servidor para usted (p.e.~cada vez 36.449 +que jale o publique cambios). 36.450 + 36.451 +El problema de almacenar frases claves en un agente es que es posible 36.452 +para un atacante bien preparado recuperar el texto plano de su frase 36.453 +clave, en algunos casos incluso si su sistema sea muy alternante. 36.454 +Es su decisión si es un riesgo aceptable. Lo que si es seguro es que 36.455 +evita reteclear. 36.456 + 36.457 +En sistemas tipo Unix, el agente se llama \command{ssh-agent}, y 36.458 +usualmente se ejecuta automáticamente cuando usted entra. Tendrá que 36.459 +usar la orden \command{ssh-add} para añadir frases claves al agente. En 36.460 +Windows, si está usando PuTTY, la orden \command{pageant} actúa como 36.461 +el agente. Añade un icono a su barra del sistema que le permitirá 36.462 +almacenar frases clave. 36.463 + 36.464 +\subsection{Configurar el lado del servidor apropiadamente} 36.465 + 36.466 +Dado que puede ser dispendioso configurar ssh si usted es nuevo, hay 36.467 +una variedad de cosas que podrían ir mal. Añada piense primero en 36.468 +Mercurial y hay mucho más en qué pensar. La mayor parte de estos 36.469 +problemas potenciales ocurren en el lado del servidor, no en el cliente. 36.470 +Las buenas noticias es que una vez tiene una configuración funcional, 36.471 +usualmente continuará trabajando indefinidamente. 36.472 + 36.473 +Antes de intentar que Mercurial hable con un servidor ssh, es mejor 36.474 +asegurarse que puede usar la orden normal \command{ssh} o \command{putty} 36.475 +para comunicarse con el servidor primero. Si tiene problemas usando 36.476 +estas órdenes directamente, de seguro Mercurial no funcionará. Pero aún, 36.477 +esconderá el problema subyacente. Cuando desee revisar un problema 36.478 +relacionado con ssh y Mercurial, debería asegurarse primero que las 36.479 +órdenes de ssh en el lado del cliente funcionan primero, \emph{antes} 36.480 +de preocuparse por si existe un problema con Mercurial. 36.481 + 36.482 +Lo primero para asegurar en el lado del servidor es que puede entrar 36.483 +desde otra máquina. Si no puede entrar con \command{ssh} o 36.484 +\command{putty}, el mensaje de error que obtenga le puede dar pistas 36.485 +de qué ha ido mal. Los problemas más comunes son los siguientes: 36.486 +\begin{itemize} 36.487 +\item Si obtiene un error de ``conexión rehusada'', es posible que no 36.488 + haya un demonio SSH corriendo en el servidor o que no pueda accederse 36.489 + a él por configuraciones de cortafuegos. 36.490 +\item Si obtiene un error de ``no hay ruta hasta el servidor'', puede 36.491 + tener la dirección del servidor incorrecta o un cortafuegos con 36.492 + bloqueo agresivo que no permitirá su existencia. 36.493 +\item Si obtiene un mensaje de ``permiso denegado'', puede que haya 36.494 + tecleado mal el usuario en el servidor, o que haya tecleado 36.495 + incorrectamente la frase clave o la clave del usuario remoto. 36.496 +\end{itemize} 36.497 +En resumen, si tiene problemas al comunicarse con el demonio ssh del 36.498 +servidor, primero asegúrese de que está corriendo. En muchos sistemas 36.499 +estará instalado, pero deshabilitado de forma predeterminada. Una vez 36.500 +que haya hecho este paso tendrá que revisar si el cortafuegos del 36.501 +servidor está configurado para recibir conexiones entrantes en el 36.502 +puerto en el cual el demonio de ssh está escuchando (usualmente el~22). 36.503 +No trate de buscar otras posibilidades exóticas o configuraciones 36.504 +erradas hasta que haya revisado primero estas dos. 36.505 + 36.506 +Si está usando un agente de autenticación en el lado del cliente para 36.507 +almacenar las frase claves de sus contraseñas, debería poder entrar al 36.508 +servidor sin necesidad de que se le solicite frases claves o 36.509 +contraseñas. Si se le pregunta alguna, a continuación algunas 36.510 +posibilidades: 36.511 +\begin{itemize} 36.512 +\item Puede haber olvidado usar \command{ssh-add} o 36.513 + \command{pageant} para guardar la frase clave. 36.514 +\item Puede haber almacenado una frase clave errónea para la llave. 36.515 +\end{itemize} 36.516 +Si se le solicita la clave del usuario remoto, hay otras posibilidades 36.517 +que deben revisarse: 36.518 +\begin{itemize} 36.519 +\item O bien el directorio del usuario o su directorio \sdirname{.ssh} 36.520 + tiene permisos excesivamente abiertos. Como resultado el daemonio 36.521 + ssh no creerá o leerá su fichero \sfilename{authorized\_keys}. 36.522 + Por ejemplo, un directorio casa o \sdirname{.ssh} causará aveces 36.523 + este síntoma. 36.524 +\item El fichero de usuario \sfilename{authorized\_keys} puede tener 36.525 + un problema. Si alguien distinto al usuario es dueño o puede 36.526 + escribir el fichero, el demonio ssh no confiará o lo leerá. 36.527 +\end{itemize} 36.528 + 36.529 +En un mundo ideal, debería poder ejecutar la siguiente orden 36.530 +exitosamente, y debería imprimir exactamente una línea de salida, 36.531 +la fecha y hora actual. 36.532 +\begin{codesample2} 36.533 + ssh miservidor fecha 36.534 +\end{codesample2} 36.535 + 36.536 +Si en su servidor tiene guión que se ejecuta a la entrada e imprime 36.537 +letreros o cualquier otra cosa, incluso cuando se ejecutan órdenes no 36.538 +interactivas como esta, debería arreglarlo antes de continuar, de 36.539 +forma que solamente imprima algo si se ejecuta interactivamente. De 36.540 +otra forma estos letreros al menos llenarán la salida de Mercurial. 36.541 +Incluso podrían causar problemas potenciales cuando se ejecuten 36.542 +órdenes de forma remota. Mercurial intenta detectar e ignorar los 36.543 +letreros en sesiones no interactivas de \command{ssh}, pero no es 36.544 +a prueba de tontos. (Si edita sus guiones de entrada en el servidor, 36.545 +la forma usual de ver si un guión de línea de comandos se ejecuta en un intérprete 36.546 +interactivo, es verificar el código de retorno de la orden 36.547 +\Verb|tty -s|.) 36.548 + 36.549 +Cuando verifique que el venerado ssh funciona en su servidor, el 36.550 +paso siguiente es asegurar que Mercurial corre en el servidor. La 36.551 +orden siguiente debería ejecutarse satisfactoriamente: 36.552 +\begin{codesample2} 36.553 + ssh miservidor hg version 36.554 +\end{codesample2} 36.555 +Si ve un mensaje de error en lugar de la salida usual de 36.556 +\hgcmd{version}, será porque no ha instalado Mercurial en 36.557 +\dirname{/usr/bin}. No se preocupe si este es el caso; no necesita 36.558 +hacerlo. Pero debería revisar los posibles problemas presentados a 36.559 +continuación: 36.560 +\begin{itemize} 36.561 +\item Está instalado Mercurial en el servidor? Se que suena trivial 36.562 + pero es mejor revisar! 36.563 +\item Tal vez la ruta de búsqueda de la interfaz de órdenes 36.564 + (normalmente vía la variable de ambiente \envar{PATH}) simplemente 36.565 + está mal configurada. 36.566 +\item Puede ser que su variable de ambiente \envar{PATH} soalamente 36.567 + apunte al lugar en el cual está el ejecutable \command{hg} si la 36.568 + sesión de entrada es interactiva. Puede suceder si establece la 36.569 + ruta en el guión de línea de comandos de entrada incorrecto. Consulte la 36.570 + documentación de su línea de órdenes. 36.571 +\item La variable de ambiente \envar{PYTHONPATH} puede requerir la 36.572 + ruta a los módulos de Mercurial en Python. Puede que ni siquiera 36.573 + está establecida; podría estar incorrecta; o puede ser que se 36.574 + establezca únicamente cuando hay entradas interactivas. 36.575 +\end{itemize} 36.576 + 36.577 +Si puede ejecutar \hgcmd{version} sobre una conexión ssh, 36.578 +felicitaciones! Ha logrado la interacción entre el cliente y el 36.579 +servidor. Ahora debería poder acceder a los repositorios de 36.580 +Mercurial que tiene el usuario en el servidor. Si tiene problemas 36.581 +con Mercurial y ssh en este punto, intente usar la opción 36.582 +\hggopt{--debug} para tener información más clara de lo que está 36.583 +sucediendo. 36.584 + 36.585 +\subsection{Compresión con ssh} 36.586 + 36.587 +Mercurial no comprime datos cuando usa el protocolo ssh, dado que 36.588 +el protocolo puede comprimir datos transparentemente. Pero el 36.589 +comportamiento predeterminado del cliente ssh es \emph{no} 36.590 +solicitar compresión. 36.591 + 36.592 +Sobre cualquier red distinta a una LAN rápida (incluso con una red 36.593 +inalámbrica), hacer uso de compresión puede mejorar el rendimiento 36.594 +de las operaciones de Mercurial que involucren la red. Por ejemplo, 36.595 +sobre WAN, alguien ha medido la compresión reduciendo la cantidad 36.596 +de tiempo requerido para clonar un repositorio particularmente 36.597 +grande de~51 minutos a~17 minutos. 36.598 + 36.599 +Tanto \command{ssh} como \command{plink} aceptan la opción 36.600 +\cmdopt{ssh}{-C} que activa la compresión. Puede editar fácilmente 36.601 +su \hgrc\ para habilitar la compresión para todos los usos de 36.602 +Mercurial sobre el protocolo ssh. 36.603 +\begin{codesample2} 36.604 + [ui] 36.605 + ssh = ssh -C 36.606 +\end{codesample2} 36.607 + 36.608 +Si usa \command{ssh}, puede reconfigurarlo para que siempre use 36.609 +compresión cuando se comunique con su servidor. Para hacerlo, 36.610 +edite su fichero \sfilename{.ssh/config} (que puede no existir 36.611 +aún), de la siguiente forma: 36.612 +\begin{codesample2} 36.613 + Host hg 36.614 + Compression yes 36.615 + HostName hg.ejemplo.com 36.616 +\end{codesample2} 36.617 +Que define un alias, \texttt{hg}. Cuando lo usa con la orden 36.618 +\command{ssh} o con una URL de Mercurial con protocolo\texttt{ssh}, 36.619 +logrará que \command{ssh} se conecte a \texttt{hg.ejemplo.com} 36.620 +con compresión. Que le dará un nombre más corto para teclear y 36.621 +compresión, los cuales por derecho propio son buenos. 36.622 + 36.623 +\section{Uso de CGI a través de HTTP} 36.624 +\label{sec:collab:cgi} 36.625 + 36.626 +Dependiendo de qué tan ambicioso sea, configurar la interfaz CGI 36.627 +de Mercurial puede tomar desde unos minutos hasta varias horas. 36.628 + 36.629 +Comenzaremos con el ejemplo más sencillo, y nos dirigiremos hacia 36.630 +configuraciones más complejas. Incluso para el caso más básico 36.631 +necesitará leer y modificar su configuración del servidor web. 36.632 + 36.633 +\begin{note} 36.634 + Configurar un servidor web es una actividad compleja, engorrosa y 36.635 + altamente dependiente del sistema. De ninguna manera podremos 36.636 + cubrir todos los casos posibles con los cuales pueda encontrarse. 36.637 + Use su discreción y juicio respecto a las secciones siguientes. 36.638 + Esté preparado para cometer muchas equivocaciones, y emplear 36.639 + bastante tiempo leyendo sus bitácoras de error del servidor. 36.640 +\end{note} 36.641 + 36.642 +\subsection{Lista de chequeo de la configuración del servidor web} 36.643 + 36.644 +Antes de continuar, tómese un tiempo para revisar ciertos aspectos de 36.645 +la configuración de su sistema: 36.646 + 36.647 +\begin{enumerate} 36.648 +\item ¿Tiene un servidor web? Mac OS X viene con Apache, pero otros 36.649 + sistemas pueden no tener un servidor web instalado. 36.650 +\item Si tiene un servidor web instalado, ¿Está ejecutándose? En la 36.651 + mayoría de sistemas, aunque esté presente, puede no estar habilitado 36.652 + de forma predeterminada. 36.653 +\item ¿u servidor está configurado para permitir ejecutar programas 36.654 + CGI en el directorio donde planea hacerlo? Casi todos los 36.655 + servidores de forma predeterminada explícitamente inhiben la 36.656 + habilidad de ejecutar programas CGI. 36.657 +\end{enumerate} 36.658 + 36.659 +Si no tiene un servidor web instalado, y no tiene cierta experiencia 36.660 +configurando Apache, debería considerar usar el servidor web 36.661 +\texttt{lighttpd} en lugar de Apache. Apache tiene una reputación 36.662 +bien ganada por su configuración barroca y confusa. 36.663 +A pesar de que \texttt{lighttpd} tiene menos características que 36.664 +Apache en ciertas áreas, las mismas no son relevantes para servir 36.665 +repositorios de Mercurial. Definitivamente es mucho más sencillo 36.666 +comenzar con \texttt{lighttpd} que con Apache. 36.667 + 36.668 +\subsection{Configuración básica de CGI} 36.669 + 36.670 +En sistemas tipo Unix es común que los usuarios tengan un subdirectorio 36.671 +con un nombre como \dirname{public\_html} en su directorio personal, 36.672 +desde el cual pueden servir páginas web. Un fichero llamado \filename{foo} 36.673 +en este directorio será visible en una URL de la forma 36.674 +\texttt{http://www.example.com/\~username/foo}. 36.675 + 36.676 +Para comenzar, encuentre el guión \sfilename{hgweb.cgi} que debería 36.677 +estar presente en su instalación de Mercurial. Si no puede 36.678 +encontrarlo rápidamente una copia local en su sistema, puede 36.679 +descargarlo del repositorio principal de Mercurial en 36.680 +\url{http://www.selenic.com/repo/hg/raw-file/tip/hgweb.cgi}. 36.681 + 36.682 +Tendrá que copiar este guión en su directorio \dirname{public\_html}, 36.683 +y asegurarse que sea ejecutable. 36.684 +\begin{codesample2} 36.685 + cp .../hgweb.cgi ~/public_html 36.686 + chmod 755 ~/public_html/hgweb.cgi 36.687 +\end{codesample2} 36.688 +El argumento \texttt{755} de la orden \command{chmod} es un poco más 36.689 +general que hacerlo ejecutable: Asegura que el guión sea ejecutable 36.690 +por cualquiera, y que el ``grupo'' y los ``otros'' \emph{no} tengan 36.691 +permiso de escritura. Si dejara los permisos de escritura abiertos, 36.692 +, el subsistema \texttt{suexec} de Apache probablemente se negaría 36.693 +a ejecutar el guión. De hecho, \texttt{suexec} también insiste en que 36.694 +el \emph{directorio} en el cual reside el guión no tenga permiso de 36.695 +escritura para otros. 36.696 +\begin{codesample2} 36.697 + chmod 755 ~/public_html 36.698 +\end{codesample2} 36.699 + 36.700 +\subsubsection{¿Qué \emph{podría} resultar mal?} 36.701 +\label{sec:collab:wtf} 36.702 + 36.703 +Cuando haya ubicado el CGI en el sitio correspondiente con un navegador 36.704 +intente visitar el URL \url{http://myhostname/~myuser/hgweb.cgi}, 36.705 +\emph{sin} dejarse abatir por un error. Hay una alta probabilidad de 36.706 +que esta primera visita al URL sea fallida, y hay muchas razones posibles 36.707 +para este comportamiento. De hecho, podría toparse con cada uno de los 36.708 +errores que describimos a continuación, así que no deje de leerlos 36.709 +cuidadosamente. A continuación presento los problemas que yo tuve en 36.710 +un sistema con Fedora~7, con una instalación nueva de Apache, y una 36.711 +cuenta de usuario que creé específicamente para desarrollar este 36.712 +ejercicio. 36.713 + 36.714 +Su servidor web puede tener directorios por usuario deshabilitados. Si 36.715 +usa Apache, busque el fichero de configuración que contenga la 36.716 +directiva \texttt{UserDir}. Si no está presente en sitio alguno, los 36.717 +directorios por usuario están deshabilitados. Si la hay, pero su 36.718 +valor es \texttt{disabled}, los directorios por usuario estarán 36.719 +deshabilitados. La directiva \texttt{UserDir} en caso contrario tendrá 36.720 +el nombre del subdirectorio bajo el cual Apache mirará en el 36.721 +directorio de cada usuario, por ejemplo \dirname{public\_html}. 36.722 + 36.723 +Los permisos de sus ficheros pueden ser demasiado restrictivos. El 36.724 +servidor web debe poder recorrer su directorio personal y los 36.725 +directorios que estén bajo \dirname{public\_html}, además de tener 36.726 +permiso para leer aquellos que estén adentro. A continuación una 36.727 +receta rápida para hacer que sus permisos estén acordes con las 36.728 +necesidades básicas. 36.729 +\begin{codesample2} 36.730 + chmod 755 ~ 36.731 + find ~/public_html -type d -print0 | xargs -0r chmod 755 36.732 + find ~/public_html -type f -print0 | xargs -0r chmod 644 36.733 +\end{codesample2} 36.734 + 36.735 +Otra posibilidad con los permisos es que obtenga una ventana 36.736 +completamente en blanco cuando trata de cargar el guión. En cuyo 36.737 +caso, es posible que los permisos que tiene son \emph{demasiado 36.738 + permisivos}. El subsistema \texttt{suexec} de Apache no ejecutará un 36.739 +guión que tenga permisos de escritura para el grupo o el planeta, por 36.740 +ejemplo. 36.741 + 36.742 +Su servidor web puede estar configurado para evitar la ejecución de 36.743 +programas CGI en los directorios de usuario. A continuación presento 36.744 +una configuración predeterminada por usuario en mi sistema Fedora. 36.745 + 36.746 +\begin{codesample2} 36.747 + <Directory /home/*/public_html> 36.748 + AllowOverride FileInfo AuthConfig Limit 36.749 + Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec 36.750 + <Limit GET POST OPTIONS> 36.751 + Order allow,deny 36.752 + Allow from all 36.753 + </Limit> 36.754 + <LimitExcept GET POST OPTIONS> 36.755 + Order deny,allow 36.756 + Deny from all 36.757 + </LimitExcept> 36.758 + </Directory> 36.759 +\end{codesample2} 36.760 +Si encuentra un grupo de instrucciones de \texttt{Directory} similares 36.761 +en su configuración de Apache, la directiva a revisar es \texttt{Options}. 36.762 +Adicione \texttt{ExecCGI} al final de esta lista en caso de que haga 36.763 +falta y reinicie su servidor web. 36.764 + 36.765 +Si resulta que Apache le muestra el texto del guión CGI en lugar de 36.766 +ejecutarlo, necesitará o bien descomentar (si se encuentra presente) o 36.767 +adicionar una directiva como la siguiente: 36.768 +\begin{codesample2} 36.769 + AddHandler cgi-script .cgi 36.770 +\end{codesample2} 36.771 + 36.772 +Otra posibilidad es que observe una traza de Python en colores 36.773 +informando que no puede importar un módulo relacionado con 36.774 +\texttt{mercurial}. Esto es un gran progreso! El servidor es capaz 36.775 +de ejecutar su guión CGI. Este error solamente ocurrirá si está 36.776 +ejecutando una instalación privada de Mercurial en lugar de una 36.777 +instalación para todo el sistema. Recuerde que el servidor que 36.778 +ejecuta el programa CGI no cuenta con variables de ambiente de las 36.779 +cuales usted si dispone en una sesión interactiva. Si este error le 36.780 +ocurre, edite su copia de \sfilename{hgweb.cgi} y siga las indicaciones 36.781 +dentro del mismo para establecer de forma adecuada su variable de 36.782 +ambiente \envar{PYTHONPATH}. 36.783 + 36.784 +Finalmente, si encuentra \emph{otra} traza a todo color de Python al visitar 36.785 +el URL: Esta seguramente se referirá a que no puede encontrar 36.786 +\dirname{/path/to/repository}. Edite su script \sfilename{hgweb.cgi} 36.787 +y reemplace la cadena \dirname{/path/to/repository} con la ruta 36.788 +completa al repositorio que desea servir. 36.789 + 36.790 +En este punto, cuando trate de recargar la página, deberá visualizar 36.791 +una linda vista HTML del historial de su repositorio. Uff! 36.792 + 36.793 +\subsubsection{Configuración de lighttpd} 36.794 + 36.795 +En mi intención de ser exhaustivo, intenté configurar 36.796 +\texttt{lighttpd}, un servidor web con creciente aceptación, para 36.797 +servir los repositorios de la misma forma como lo describí 36.798 +anteriormente con Apache. Después de superar los problemas que mostré 36.799 +con Apache, muchos de los cuáles no son específicos del servidor. Por 36.800 +lo tanto estaba seguro de que mis permisos para directorios y ficheros 36.801 +eran correctos y que mi guión \sfilename{hgweb.cgi} también lo era. 36.802 + 36.803 +Dado que ya Apache estaba en ejecución correctamente, lograr que 36.804 +\texttt{lighttpd} sirviera mi repositorio fue rápido (en otras 36.805 +palabras, si está tratando de usar \texttt{lighttpd}, debe leer la 36.806 +sección de Apache). Primero tuve que editar la sección 36.807 +\texttt{mod\_access} para habilitar \texttt{mod\_cgi} y 36.808 +\texttt{mod\_userdir}, los cuales estaban inhabilitados en mi 36.809 +instalación predeterminada. Añadí posteriormente unas líneas al final 36.810 +del fichero de configuración, para hacer lo propio con los módulos. 36.811 +\begin{codesample2} 36.812 + userdir.path = "public_html" 36.813 + cgi.assign = ( ".cgi" => "" ) 36.814 +\end{codesample2} 36.815 +Hecho esto, \texttt{lighttpd} funcionó inmediatamente para 36.816 +mí. Configuré \texttt{lighttpd} antes que Apache, tuve casi los mismos 36.817 +reparos a nivel de configuración del sistema que con Apache. De todas 36.818 +maneras, considero que \texttt{lighttpd} es bastante más sencillo de 36.819 +configurar que Apache, a pesar de haber usado Apache por lo menos por 36.820 +una década, y esta fue mi primera experiencia con \texttt{lighttpd}. 36.821 + 36.822 +\subsection{Compartir varios repositorios con un guión CGI} 36.823 + 36.824 +El guión \sfilename{hgweb.cgi} permite publicar únicamente un 36.825 +repositorio, una restricción frustrante. Si desea publicar más de uno 36.826 +sin complicarse con varias copias del mismo guión, cada una con un 36.827 +nombre distinto, resulta mucho mejor usar el guión 36.828 +\sfilename{hgwebdir.cgi}. 36.829 + 36.830 +El procedimiento para configurar \sfilename{hgwebdir.cgi} tiene una 36.831 +porción adicional frente al trabajo requerido con 36.832 +\sfilename{hgweb.cgi}. Primero se debe obtener una copia del 36.833 +guión. Si no tiene una a mano, puede descargar una copia del ftp 36.834 +principal del repositorio de Mercurial en 36.835 +\url{http://www.selenic.com/repo/hg/raw-file/tip/hgwebdir.cgi}. 36.836 + 36.837 +Necesitará una copia del guión en su directorio \dirname{public\_html}, 36.838 +y asegurarse de que sea ejecutable. 36.839 +\begin{codesample2} 36.840 + cp .../hgwebdir.cgi ~/public_html 36.841 + chmod 755 ~/public_html ~/public_html/hgwebdir.cgi 36.842 +\end{codesample2} 36.843 +Con la configuración básica, intente visitar en su navegador 36.844 +\url{http://myhostname/~myuser/hgwebdir.cgi}. Debería mostrar una 36.845 +lista vacía de repositorios. Si obtiene una ventana en blanco o un 36.846 +mensaje de error, verifique la lista de problemas potenciales en la 36.847 +sección~\ref{sec:collab:wtf}. 36.848 + 36.849 +El guión \sfilename{hgwebdir.cgi} se apoya en un fichero externo de 36.850 +configuración. En principio, busca un fichero llamado 36.851 +\sfilename{hgweb.config} en el mismo directorio. Tendrá que crear el 36.852 +fichero, y permitir lectura de todo el mundo. El formato del fichero 36.853 +es similar a un fichero ``ini'' de Windows, que puede interpretar el módulo 36.854 +\texttt{ConfigParser}~\cite{web:configparser} de Python. 36.855 + 36.856 +La forma más sencilla de configurar \sfilename{hgwebdir.cgi} es con 36.857 +una sección llamada \texttt{collections}. Esta publicará automáticamente 36.858 +\emph{todos} los repositorios en los directorios que usted 36.859 +especifique. La sección debería lucir así: 36.860 +\begin{codesample2} 36.861 + [collections] 36.862 + /mi/ruta = /mi/ruta 36.863 +\end{codesample2} 36.864 +Mercurial lo interpreta buscando el nombre del directorio que esté a la 36.865 +\emph{derecha} del símbolo ``\texttt{=}''; encontrando repositorios en 36.866 +la jerarquía de directorios; y usando el texto a la \emph{izquierda} 36.867 +para eliminar el texto de los nombres que mostrará en la interfaz 36.868 +web. El componente restante de la ruta después de esta eliminación 36.869 +usualmente se llama ``ruta virtual''. 36.870 + 36.871 +Dado el ejemplo de arriba, si tenemos un repositorio cuya ruta local es 36.872 +\dirname{/mi/ruta/este/repo}, el guión CGI eliminará la porción inicial 36.873 +\dirname{/mi/ruta} del nombre y publicará el repositorio con una ruta 36.874 +virtual \dirname{este/repo}. Si el URL base de nuestro guión CGI es 36.875 +\url{http://myhostname/~myuser/hgwebdir.cgi}, el URL completo al 36.876 +repositorio será 36.877 +\url{http://myhostname/~myuser/hgwebdir.cgi/this/repo}. 36.878 + 36.879 +Si reemplazamos \dirname{/mi/ruta} en el lado izquierdo de este 36.880 +ejemplo con \dirname{/mi}, \sfilename{hgwebdir.cgi} eliminará solamente 36.881 +\dirname{/mi} del nombre del repositorio, y nos ofrecerá la ruta 36.882 +virtual \dirname{ruta/este/repo} en lugar de \dirname{este/repo}. 36.883 + 36.884 +El guión \sfilename{hgwebdir.cgi} buscará recursivamente en cada 36.885 +directorio listado en la sección \texttt{collections} de su fichero de 36.886 +configuración, pero \texttt{no} hará el recorrido recursivo dentro de 36.887 +los repositorios que encuentre. 36.888 + 36.889 +El mecanismo de \texttt{collections} permite publicar fácilmente 36.890 +repositorios de una forma ``hacer y olvidar''. Solamente requiere 36.891 +configurar el guión CGI y el fichero de configuración una vez. 36.892 +Después de eso puede publicar y sacar de publicación un repositorio en 36.893 +cualquier momento incluyéndolo o excluyéndolo de la jerarquía de 36.894 +directorios en la cual le haya indicado a \sfilename{hgwebdir.cgi} que 36.895 +mirase. 36.896 + 36.897 +\subsubsection{Especificación explícita de los repositorios a publicar} 36.898 + 36.899 +Además del mecanismo \texttt{collections}, el guión 36.900 +\sfilename{hgwebdir.cgi} le permite publicar una lista específica de 36.901 +repositorios. Para hacerlo, cree una sección \texttt{paths}, con los 36.902 +contenidos de la siguiente forma: 36.903 +\begin{codesample2} 36.904 + [paths] 36.905 + repo1 = /mi/ruta/a/un/repo 36.906 + repo2 = /ruta/a/otro/repo 36.907 +\end{codesample2} 36.908 +En este caso, la ruta virtual (el componente que aparecerá en el URL) 36.909 +está en el lado derecho de cada definición, mientras que la ruta al 36.910 +repositorio está a la derecha. Note que no tiene que haber relación 36.911 +alguna entre la ruta virtual que elija y el lugar del repositorio en 36.912 +su sistema de ficheros. 36.913 + 36.914 +Si lo desea, puede usar los dos mecanismos \texttt{collections} y 36.915 +\texttt{paths} simultáneamente en un sólo fichero de configuración. 36.916 + 36.917 +\begin{note} 36.918 + Si varios repositorios tienen la misma ruta virtual, 36.919 + \sfilename{hgwebdir.cgi} no reportará error. Pero se comportará 36.920 + impredeciblemente. 36.921 +\end{note} 36.922 + 36.923 +\subsection{Descarga de ficheros fuente} 36.924 + 36.925 +La interfaz web de Mercurial permite a los usuarios descargar 36.926 +un conjunto de cualquier revisión. Este fichero contendrá una réplica 36.927 +del directorio de trabajo en la revisión en cuestión, pero no 36.928 +contendrá una copia de los datos del repositorio. 36.929 + 36.930 +De forma predeterminada esta característica no está habilitada. Para 36.931 +lograrlo adicione un \rcitem{web}{allow\_archive} a la sección \rcsection{web} 36.932 +de su fichero \hgrc. 36.933 + 36.934 +\subsection{Opciones de configuración en Web} 36.935 + 36.936 +Las interfaces web de Mercurial (la orden \hgcmd{serve}, y los guiones 36.937 +\sfilename{hgweb.cgi} y \sfilename{hgwebdir.cgi}) tienen varias 36.938 +opciones de configuración para establecer. Todas ellas en la sección 36.939 +\rcsection{web}. 36.940 +\begin{itemize} 36.941 +\item[\rcitem{web}{allow\_archive}] Determina cuáles tipos de ficheros 36.942 + de descarga soportará Mercurial. Si habilita esta característica, 36.943 + los usuarios de la interfaz web podrán descargar una copia de la 36.944 + revisión del repositorio que estén viendo. Para activar la 36.945 + característica de descarga de fichero, el valor tendrá una secuencia 36.946 + de palabras extraídas de la lista de abajo. 36.947 + \begin{itemize} 36.948 + \item[\texttt{bz2}] Un fichero \command{tar} con el método de 36.949 + compresión \texttt{bzip2}. Tiene la mejor tasa de compresión, 36.950 + pero usa más tiempo de procesamiento en el servidor. 36.951 + \item[\texttt{gz}] Un fichero \command{tar}, comprimido con 36.952 + \texttt{gzip}. 36.953 + \item[\texttt{zip}] Un fichero \command{zip}, comprimido con LZW. 36.954 + Este formato posee la peor tasa de compresión, pero es muy usado en 36.955 + el mundo Windows. 36.956 + \end{itemize} 36.957 + Si da una lista vacía o no tiene la entrada 36.958 + \rcitem{web}{allow\_archive}, esta característica se deshabilitará. 36.959 + A continuación un ejemplo de cómo habilitar los tres formatos soportados. 36.960 + \begin{codesample4} 36.961 + [web] 36.962 + allow_archive = bz2 gz zip 36.963 + \end{codesample4} 36.964 +\item[\rcitem{web}{allowpull}] Booleano. Determina si la interfaz web 36.965 + permite a los usuarios remotos emplear \hgcmd{pull} y \hgcmd{clone} 36.966 + sobre el repositorio~HTTP. Si se coloca \texttt{no} o 36.967 + \texttt{false}, solamente la porción de los procesos 36.968 + ``orientados-a-humanos'' se habilita de la interfaz web. 36.969 +\item[\rcitem{web}{contact}] Cadena. Una cadena en forma libre (pero 36.970 + preferiblemente corta) que identifica a la persona o grupo a cargo 36.971 + del repositorio. Usualmente contiene el nombre y la dirección de 36.972 + correo electrónico de una persona o de una lista de correo. Aveces 36.973 + tiene sentido colocar esta opción en el fichero \sfilename{.hg/hgrc} 36.974 + del repositorio, pero en otras oportunidades en el \hgrc\ global si 36.975 + todos los repositorios tienen un único mantenedor. 36.976 +\item[\rcitem{web}{maxchanges}] Entero. La cantidad máxima de 36.977 + conjuntos de cambios a mostrar de forma predeterminada en cada página. 36.978 +\item[\rcitem{web}{maxfiles}] Entero. La cantidad máxima 36.979 + predeterminada de ficheros modificados a desplegar en una página. 36.980 +\item[\rcitem{web}{stripes}] Entero. Si la interfaz web despliega 36.981 + ``franjas'' para facilitar la visualización alineada de filas cuando 36.982 + se ve una tabla, este valor controla la cantidad de filas en cada 36.983 + franja. 36.984 +\item[\rcitem{web}{style}] Controla la plantilla que Mercurial usa para 36.985 + desplegar la interfaz web. Mercurial viene con dos plantillas web, 36.986 + llamadas \texttt{default} y \texttt{gitweb} (La primera es 36.987 + visualmente más atractiva). Puede especificar una plantilla propia; 36.988 + consulte el capítulo~\ref{chap:template}. A continuación mostramos 36.989 + cómo habilitar el estilo \texttt{gitweb}. 36.990 + \begin{codesample4} 36.991 + [web] 36.992 + style = gitweb 36.993 + \end{codesample4} 36.994 +\item[\rcitem{web}{templates}] Ruta. Directorio en el que se buscarán 36.995 + los ficheros plantilla. De forma predeterminada, busca en el 36.996 + directorio en el cual fue instalado. 36.997 +\end{itemize} 36.998 +Si usa \sfilename{hgwebdir.cgi}, puede añadir otras opciones de 36.999 +configuración en una sección \section{web} del fichero 36.1000 +\sfilename{hgweb.config} en lugar del fichero \hgrc\, si lo considera 36.1001 +más conveniente. Estas opciones son \rcitem{web}{motd} y 36.1002 +\rcitem{web}{style}. 36.1003 + 36.1004 +\subsubsection{Opciones específicas para repositorios individuales} 36.1005 + 36.1006 +Ciertas opciones de configuración de \rcsection{web} deben estar 36.1007 +ubicadas en el \sfilename{.hg/hgrc} de un repositorio en lugar del 36.1008 +fichero del usuario o el \hgrc global. 36.1009 +\begin{itemize} 36.1010 +\item[\rcitem{web}{description}] Cadena. Una cadena de forma 36.1011 + libre (preferiblemente corta) que describa los contenidos o el 36.1012 + propósito del repositorio. 36.1013 +\item[\rcitem{web}{name}] Cadena. El nombre para visualizar en la 36.1014 + interfaz web del repositorio. Sustituye el nombre predeterminado, el 36.1015 + cual es el último componente de la ruta del repositorio. 36.1016 +\end{itemize} 36.1017 + 36.1018 +\subsubsection{Opciones específicas a la orden \hgcmd{serve}} 36.1019 + 36.1020 +Algunas opciones en la sección \rcsection{web} de un fichero \hgrc\ 36.1021 +son de uso exclusivo para la orden \hgcmd{serve}. 36.1022 +\begin{itemize} 36.1023 +\item[\rcitem{web}{accesslog}] Ruta. El nombre del fichero en el cual 36.1024 + se escribe la bitácora de acceso. En principio, la orden 36.1025 + \hgcmd{serve} escribe esta información a la salida estándar, no a un 36.1026 + fichero. Las líneas de la bitácora se escriben en un formato de 36.1027 + fichero ``combinado'' estándar, usado por casi todos los servidores 36.1028 + web. 36.1029 +\item[\rcitem{web}{address}] Cadena. La dirección local en la cual el 36.1030 + servidor debe escuchar peticiones entrantes. En principio, el 36.1031 + servidor escucha en todas las direcciones. 36.1032 +\item[\rcitem{web}{errorlog}] Ruta. El nombre de un fichero en el 36.1033 + cual escribir la bitácora de error. En principio, la orden 36.1034 + \hgcmd{serve} escribe esta información en la salida de error 36.1035 + estándar, no a un fichero. 36.1036 +\item[\rcitem{web}{ipv6}] Booleano. Si se usa o no el protocolo 36.1037 + IPv6. En principio, IPv6 no se usa. 36.1038 +\item[\rcitem{web}{port}] Entero. El número del puerto~TCP en el cuál 36.1039 + el servidor escuchará. El puerto predeterminado es el~8000. 36.1040 +\end{itemize} 36.1041 + 36.1042 +\subsubsection{Elegir el fichero \hgrc\ correcto para las 36.1043 + configuraciones de \rcsection{web}} 36.1044 + 36.1045 +Es importante recordar que un servidor web como Apache o 36.1046 +\texttt{lighttpd} se ejecutarán bajo el usuario~ID que generalmente no 36.1047 +es el suyo Los guiones CGI ejecutados por su servidor, tales como 36.1048 +\sfilename{hgweb.cgi}, se ejecutarán también con el usuario~ID. 36.1049 + 36.1050 +Si añade opciones \rcsection{web} a su fichero personal \hgrc\, Los 36.1051 +guiones CGI no leerán tal fichero \hgrc\. Tales configuraciones 36.1052 +solamente afectarán el comportamiento de la orden \hgcmd{serve} cuando 36.1053 +usted lo ejecuta. Para logar que los guiones CGI vean sus 36.1054 +configuraciones, o bien cree un fichero \hgrc\ en el directorio hogar 36.1055 +del usuario ID que ejecuta su servidor web, o añada tales 36.1056 +configuraciones al fichero global \hgrc. 36.1057 + 36.1058 + 36.1059 +%%% Local Variables: 36.1060 +%%% mode: latex 36.1061 +%%% TeX-master: "00book" 36.1062 +%%% End:
37.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 37.2 +++ b/es/concepts.tex Thu Jan 29 22:00:07 2009 -0800 37.3 @@ -0,0 +1,650 @@ 37.4 +\chapter{Tras bambalinas} 37.5 +\label{chap:concepts} 37.6 + 37.7 +A diferencia de varios sistemas de control de revisiones, los 37.8 +conceptos en los que se fundamenta Mercurial son lo suficientemente 37.9 +simples como para entender fácilmente cómo funciona el software. 37.10 +Saber esto no es necesario, pero considero útil tener un ``modelo 37.11 +mental'' de qué es lo que sucede. 37.12 + 37.13 +Comprender esto me da la confianza de que Mercurial ha sido 37.14 +cuidadosamente diseñado para ser tanto \emph{seguro} como 37.15 +\emph{eficiente}. Y tal vez con la misma importancia, si es fácil 37.16 +para mí hacerme a una idea adecuada de qué está haciendo el software 37.17 +cuando llevo a cabo una tarea relacionada con control de revisiones, 37.18 +es menos probable que me sosprenda su comportamiento. 37.19 + 37.20 +En este capítulo, cubriremos inicialmente los conceptos centrales 37.21 +del diseño de Mercurial, y luego discutiremos algunos detalles 37.22 +interesantes de su implementación. 37.23 + 37.24 +\section{Registro del historial de Mercurial} 37.25 + 37.26 +\subsection{Seguir el historial de un único fichero} 37.27 + 37.28 +Cuando Mercurial sigue las modificaciones a un fichero, guarda el 37.29 +historial de dicho fichero en un objeto de metadatos llamado 37.30 +\emph{filelog}\ndt{Fichero de registro}. Cada entrada en el fichero 37.31 +de registro contiene suficiente información para reconstruir una 37.32 +revisión del fichero que se está siguiendo. Los ficheros de registro 37.33 +son almacenados como ficheros el el directorio 37.34 +\sdirname{.hg/store/data}. Un fichero de registro contiene dos tipos 37.35 +de información: datos de revisiones, y un índice para ayudar a 37.36 +Mercurial a buscar revisiones eficientemente. 37.37 + 37.38 +El fichero de registro de un fichero grande, o con un historial muy 37.39 +largo, es guardado como ficheros separados para datos (sufijo 37.40 +``\texttt{.d}'') y para el índice (sufijo ``\texttt{.i}''). Para 37.41 +ficheros pequeños con un historial pequeño, los datos de revisiones y 37.42 +el índice son combinados en un único fichero ``\texttt{.i}''. La 37.43 +correspondencia entre un fichero en el directorio de trabajo y el 37.44 +fichero de registro que hace seguimiento a su historial en el 37.45 +repositorio se ilustra en la figura~\ref{fig:concepts:filelog}. 37.46 + 37.47 +\begin{figure}[ht] 37.48 + \centering 37.49 + \grafix{filelog} 37.50 + \caption{Relación entre ficheros en el directorio de trabajo y 37.51 + ficheros de registro en el repositorio} 37.52 + \label{fig:concepts:filelog} 37.53 +\end{figure} 37.54 + 37.55 +\subsection{Administración de ficheros monitoreados} 37.56 + 37.57 +Mercurial usa una estructura llamada \emph{manifiesto} para 37.58 +% TODO collect together => centralizar 37.59 +centralizar la información que maneja acerca de los ficheros que 37.60 +monitorea. Cada entrada en el manifiesto contiene información acerca 37.61 +de los ficheros involucrados en un único conjunto de cambios. Una 37.62 +entrada registra qué ficheros están presentes en el conjunto de 37.63 +cambios, la revisión de cada fichero, y otros cuantos metadatos del 37.64 +mismo. 37.65 + 37.66 +\subsection{Registro de información del conjunto de cambios} 37.67 + 37.68 +La \emph{bitácora de cambios} contiene información acerca de cada 37.69 +conjunto de cambios. Cada revisión indica quién consignó un cambio, el 37.70 +comentario para el conjunto de cambios, otros datos relacionados con 37.71 +el conjunto de cambios, y la revisión del manifiesto a usar. 37.72 + 37.73 +\subsection{Relaciones entre revisiones} 37.74 + 37.75 +Dentro de una bitácora de cambios, un manifiesto, o un fichero de 37.76 +registro, cada revisión conserva un apuntador a su padre inmediato 37.77 +(o sus dos padres, si es la revisión de una fusión). Como menciońe 37.78 +anteriormente, también hay relaciones entre revisiones \emph{a través} 37.79 +de estas estructuras, y tienen naturaleza jerárquica. 37.80 + 37.81 +Por cada conjunto de cambios en un repositorio, hay exactamente una 37.82 +revisión almacenada en la bitácora de cambios. Cada revisión de la 37.83 +bitácora de cambios contiene un apuntador a una única revisión del 37.84 +manifiesto. Una revisión del manifiesto almacena un apuntador a una 37.85 +única revisión de cada fichero de registro al que se le hacía 37.86 +seguimiento cuando fue creado el conjunto de cambios. Estas relaciones 37.87 +se ilustran en la figura~\ref{fig:concepts:metadata}. 37.88 + 37.89 +\begin{figure}[ht] 37.90 + \centering 37.91 + \grafix{metadata} 37.92 + \caption{Relaciones entre metadatos} 37.93 + \label{fig:concepts:metadata} 37.94 +\end{figure} 37.95 + 37.96 +Como lo muestra la figura, \emph{no} hay una relación ``uno a uno'' 37.97 +entre las revisiones en el conjunto de cambios, el manifiesto, o el 37.98 +fichero de registro. Si el manifiesto no ha sido modificado de un 37.99 +conjunto de cambios a otro, las entradas en la bitácora de cambios 37.100 +para esos conjuntos de cambios apuntarán a la misma revisión del 37.101 +manifiesto. Si un fichero monitoreado por Mercurial no sufre ningún 37.102 +cambio de un conjunto de cambios a otro, la entrada para dicho fichero 37.103 +en las dos revisiones del manifiesto apuntará a la misma revisión de 37.104 +su fichero de registro. 37.105 + 37.106 +\section{Almacenamiento seguro y eficiente} 37.107 + 37.108 +La base común de las bitácoras de cambios, los manifiestos, y los 37.109 +ficheros de registros es provista por una única estructura llamada el 37.110 +\emph{revlog}\ndt{Contracción de \emph{revision log}, registro de 37.111 +revisión.}. 37.112 + 37.113 +\subsection{Almacenamiento eficiente} 37.114 + 37.115 +El revlog provee almacenamiento eficiente de revisiones por medio del 37.116 +mecanismo de \emph{deltas}\ndt{Diferencias.}. En vez de almacenar una 37.117 +copia completa del fichero por cada revisión, almacena los cambios 37.118 +necesarios para transformar una revisión anterior en la nueva 37.119 +revisión. Para muchos tipos de fichero, estos deltas son típicamente 37.120 +de una fracción porcentual del tamaño de una copia completa del 37.121 +fichero. 37.122 + 37.123 +Algunos sistemas de control de revisiones obsoletos sólo pueden 37.124 +manipular deltas de ficheros de texto plano. Ellos o bien almacenan 37.125 +los ficheros binarios como instantáneas completas, o codificados en 37.126 +alguna representación de texto plano adecuada, y ambas alternativas 37.127 +son enfoques que desperdician bastantes recursos. Mercurial puede 37.128 +manejar deltas de ficheros con contenido binario arbitrario; no 37.129 +necesita tratar el texto plano como un caso especial. 37.130 + 37.131 +\subsection{Operación segura} 37.132 +\label{sec:concepts:txn} 37.133 + 37.134 +Mercurial sólo \emph{añade} datos al final de los ficheros de revlog. Nunca 37.135 +modifica ninguna sección de un fichero una vez ha sido escrita. Esto es más 37.136 +robusto y eficiente que otros esquemas que requieren modificar o reescribir 37.137 +datos. 37.138 + 37.139 +Adicionalmente, Mercurial trata cada escritura como parte de una 37.140 +\emph{transacción}, que puede cubrir varios ficheros. Una transacción es 37.141 +\emph{atómica}: o bien la transacción tiene éxito y entonces todos sus efectos 37.142 +son visibles para todos los lectores, o la operación completa es cancelada. 37.143 +% TODO atomicidad no existe de acuerdo a DRAE, reemplazar 37.144 +Esta garantía de atomicidad implica que, si usted está ejecutando dos copias de 37.145 +Mercurial, donde una de ellas está leyendo datos y la otra los está escribiendo, 37.146 +el lector nunca verá un resultado escrito parcialmente que podría confundirlo. 37.147 + 37.148 +El hecho de que Mercurial sólo hace adiciones a los ficheros hace más fácil 37.149 +proveer esta garantía transaccional. A medida que sea más fácil hacer 37.150 +operaciones como ésta, más confianza tendrá usted en que sean hechas 37.151 +correctamente. 37.152 + 37.153 +\subsection{Recuperación rápida de datos} 37.154 + 37.155 +Mercurial evita ingeniosamente un problema común a todos los sistemas de control 37.156 +de revisiones anteriores> el problema de la 37.157 +\emph{recuperación\ndt{\emph{Retrieval}. Recuperación en el sentido de traer los 37.158 +datos, o reconstruirlos a partir de otros datos, pero no debido a una falla o 37.159 +calamidad, sino a la operación normal del sistema.} ineficiente de datos}. 37.160 +Muchos sistemas de control de revisiones almacenan los contenidos de una 37.161 +revisión como una serie incremental de modificaciones a una ``instantánea''. 37.162 +Para reconstruir una versión cualquiera, primero usted debe leer la instantánea, 37.163 +y luego cada una de las revisiones entre la instantánea y su versión objetivo. 37.164 +Entre más largo sea el historial de un fichero, más revisiones deben ser leídas, 37.165 +y por tanto toma más tiempo reconstruir una versión particular. 37.166 + 37.167 +\begin{figure}[ht] 37.168 + \centering 37.169 + \grafix{snapshot} 37.170 + \caption{Instantánea de un revlog, con deltas incrementales} 37.171 + \label{fig:concepts:snapshot} 37.172 +\end{figure} 37.173 + 37.174 +La innovación que aplica Mercurial a este problema es simple pero efectiva. 37.175 +Una vez la cantidad de información de deltas acumulada desde la última 37.176 +instantánea excede un umbral fijado de antemano, se almacena una nueva 37.177 +instantánea (comprimida, por supuesto), en lugar de otro delta. Esto hace 37.178 +posible reconstruir \emph{cualquier} versión de un fichero rápidamente. Este 37.179 +enfoque funciona tan bien que desde entonces ha sido copiado por otros sistemas 37.180 +de control de revisiones. 37.181 + 37.182 +La figura~\ref{fig:concepts:snapshot} ilustra la idea. En una entrada en el 37.183 +fichero índice de un revlog, Mercurial almacena el rango de entradas (deltas) 37.184 +del fichero de datos que se deben leer para reconstruir una revisión en 37.185 +particular. 37.186 + 37.187 +\subsubsection{Nota al margen: la influencia de la compresión de vídeo} 37.188 + 37.189 +Si le es familiar la compresión de vídeo, o ha mirado alguna vez una emisión de 37.190 +TV a través de cable digital o un servicio de satélite, puede que sepa que la 37.191 +mayor parte de los esquemas de compresión de vídeo almacenan cada cuadro del 37.192 +mismo como un delta contra el cuadro predecesor. Adicionalmente, estos esquemas 37.193 +usan técnicas de compresión ``con pérdida'' para aumentar la tasa de 37.194 +compresión, por lo que los errores visuales se acumulan a lo largo de una 37.195 +cantidad de deltas inter-cuadros. 37.196 + 37.197 +Ya que existe la posibilidad de que un flujo de vídeo se ``pierda'' 37.198 +ocasionalmente debido a fallas en la señal, y para limitar la acumulación de 37.199 +errores introducida por la compresión con pérdidas, los codificadores de vídeo 37.200 +insertan periódicamente un cuadro completo (también llamado ``cuadro clave'') en 37.201 +el flujo de vídeo; el siguiente delta es generado con respecto a dicho cuadro. 37.202 +Esto quiere decir que si la señal de vídeo se interrumpe, se reanudará una vez 37.203 +se reciba el siguiente cuadro clave. Además, la acumulación de errores de 37.204 +codificación se reinicia con cada cuadro clave. 37.205 + 37.206 +\subsection{Identificación e integridad fuerte} 37.207 + 37.208 +Además de la información de deltas e instantáneas, una entrada en un 37.209 +% TODO de pronto aclarar qué diablos es un hash? 37.210 +revlog contiene un hash criptográfico de los datos que representa. 37.211 +Esto hace difícil falsificar el contenido de una revisión, y hace 37.212 +fácil detectar una corrupción accidental. 37.213 + 37.214 +Los hashes proveen más que una simple revisión de corrupción: son 37.215 +usados como los identificadores para las revisiones. 37.216 +% TODO no entendí completamente la frase a continuación 37.217 +Los hashes de 37.218 +identificación de conjuntos de cambios que usted ve como usuario final 37.219 +son de las revisiones de la bitácora de cambios. Aunque los ficheros 37.220 +de registro y el manifiesto también usan hashes, Mercurial sólo los 37.221 +usa tras bambalinas. 37.222 + 37.223 +Mercurial verifica que los hashes sean correctos cuando recupera 37.224 +revisiones de ficheros y cuando jala cambios desde otro repositorio. 37.225 +Si se encuentra un problema de integridad, Mercurial se quejará y 37.226 +detendrá cualquier operación que esté haciendo. 37.227 + 37.228 +Además del efecto que tiene en la eficiencia en la recuperación, el 37.229 +uso periódico de instantáneas de Mercurial lo hace más robusto frente 37.230 +a la corrupción parcial de datos. Si un fichero de registro se 37.231 +corrompe parcialmente debido a un error de hardware o del sistema, a 37.232 +menudo es posible reconstruir algunas o la mayoría de las revisiones a 37.233 +partir de las secciones no corrompidas del fichero de registro, tanto 37.234 +antes como después de la sección corrompida. Esto no sería posible con 37.235 +un sistema de almacenamiento basado únicamente en deltas. 37.236 + 37.237 +\section{Historial de revisiones, ramas y fusiones} 37.238 + 37.239 +Cada entrada en el revlog de Mercurial conoce la identidad de la 37.240 +revisión de su ancestro inmediato, al que se conoce usualmente como su 37.241 +\emph{padre}. De hecho, una revisión contiene sitio no sólo para un 37.242 +padre, sino para dos. Mercurial usa un hash especial, llamado el 37.243 +``ID nulo'', para representar la idea de ``no hay padre aquí''. Este 37.244 +hash es simplemente una cadena de ceros. 37.245 + 37.246 +En la figura~\ref{fig:concepts:revlog} usted puede ver un ejemplo de 37.247 +la estructura conceptual de un revlog. Los ficheros de registro, 37.248 +manifiestos, y bitácoras de cambios comparten la misma estructura; 37.249 +sólo difieren en el tipo de datos almacenados en cada delta o 37.250 +instantánea. 37.251 + 37.252 +La primera revisión en un revlog (al final de la imagen) tiene como 37.253 +padre al ID nulo, en las dos ranuras disponibles para padres. En una 37.254 +revisión normal, la primera ranura para padres contiene el ID de la 37.255 +revisión padre, y la segunda contiene el ID nulo, señalando así que la 37.256 +revisión sólo tiene un padre real. Un par de revisiones que tenga el 37.257 +mismo ID padre son ramas. Una revisión que representa una fusión entre 37.258 +ramas tiene dos IDs de revisión normales en sus ranuras para padres. 37.259 + 37.260 +\begin{figure}[ht] 37.261 + \centering 37.262 + \grafix{revlog} 37.263 + \caption{} 37.264 + \label{fig:concepts:revlog} 37.265 +\end{figure} 37.266 + 37.267 +\section{El directorio de trabajo} 37.268 + 37.269 +% TODO revisar párrafo, no me convence la traducción 37.270 +En el directorio de trabajo, Mercurial almacena una instantánea de los 37.271 +ficheros del repositorio como si fueran los de un conjunto de cambios 37.272 +particular. 37.273 + 37.274 +El directorio de trabajo ``sabe'' qué conjunto de cambios contiene. 37.275 +Cuando usted actualiza el directorio de trabajo para que contenga un 37.276 +conjunto de cambios particular, Mercurial busca la revisión adecuada 37.277 +del manifiesto para averiguar qué ficheros estaba monitoreando cuando 37.278 +se hizo la consignación del conjunto de cambios, y qué revisión de 37.279 +cada fichero era la actual en ese momento. Luego de eso, recrea una 37.280 +copia de cada uno de esos ficheros, con los mismos contenidos que 37.281 +tenían cuando fue consignado el conjunto de cambios. 37.282 + 37.283 +El \emph{estado de directorio}\ndt{dirstate, en inglés en el 37.284 +original.} contiene el conocimiento de Mercurial acerca del directorio 37.285 +de trabajo. Allí se detalla a qué conjunto de cambios es actualizado 37.286 +el directorio de trabajo, y todos los ficheros que Mercurial está 37.287 +monitoreando en este directorio. 37.288 + 37.289 +Tal como la revisión de un revlog tiene espacio para dos padres, para 37.290 +que pueda representar tanto una revisión normal (con un solo padre) o 37.291 +una fusión de dos revisiones anteriores, el estado de directorio tiene 37.292 +espacio para dos padres. Cuando usted usa el comando \hgcmd{update}, 37.293 +el conjunto de cambios al que usted se actualiza es almacenado en la 37.294 +casilla destinada al ``primer padre'', y un ID nulo es almacenado en 37.295 +la segunda. Cuando usted hace una fusión (\hgcmd{merge}) con otro 37.296 +conjunto de cambios, la casilla para el primer padre permanece sin 37.297 +cambios, y la casilla para el segundo es actualizada con el conjunto 37.298 +de cambios con el que usted acaba de hacer la fusión. El comando 37.299 +\hgcmd{parents} le indica cuáles son los padres del estado de 37.300 +directorio. 37.301 + 37.302 +\subsection{Qué pasa en una consignación} 37.303 + 37.304 +El estado de directorio almacena información sobre los padres para 37.305 +algo más que mero registro. Mercurial usa los padres del estado de 37.306 +directorio como \emph{los padres de un nuevo conjunto de cambios} 37.307 +cuando usted hace una consignación. 37.308 + 37.309 +\begin{figure}[ht] 37.310 + \centering 37.311 + \grafix{wdir} 37.312 + \caption{El directorio de trabajo puede tener dos padres} 37.313 + \label{fig:concepts:wdir} 37.314 +\end{figure} 37.315 + 37.316 +La figura~\ref{fig:concepts:wdir} muestra el estado normal del 37.317 +directorio de trabajo, que tiene un único conjunto de cambios como 37.318 +padre. Dicho conjunto de cambios es la \emph{punta}, el conjunto de 37.319 +cambios más reciente en el repositorio que no tiene hijos. 37.320 + 37.321 +\begin{figure}[ht] 37.322 + \centering 37.323 + \grafix{wdir-after-commit} 37.324 + \caption{El directorio de trabajo obtiene nuevos padres luego de una 37.325 + consignación} 37.326 + \label{fig:concepts:wdir-after-commit} 37.327 +\end{figure} 37.328 + 37.329 +Es útil pensar en el directorio de trabajo como en ``el conjunto de 37.330 +cambios que estoy a punto de enviar''. Cualquier fichero que usted le 37.331 +diga a Mercurial que fue añadido, borrado, renombrado o copiado, se 37.332 +verá reflejado en ese conjunto de cambios, como también se verán las 37.333 +modificaciones a cualquiera de los ficheros que Mercurial ya esté 37.334 +monitoreando; el nuevo conjunto de cambios dentrá los padres del 37.335 +directorio de trabajo como propios. 37.336 + 37.337 +Luego de una consignación, Mercurial actualizará los padres del 37.338 +directorio de trabajo, de tal manera que el primer padre sea el ID del 37.339 +nuevo conjunto de cambios, y el segundo sea el ID nulo. Esto puede 37.340 +verse en la figura~\ref{fig:concepts:wdir-after-commit}. Mercurial no 37.341 +toca ninguno de los ficheros del directorio de trabajo cuando usted 37.342 +hace la consignación; sólo modifica el estado de directorio para 37.343 +anotar sus nuevos padres. 37.344 + 37.345 +\subsection{Creación de un nuevo frente} 37.346 + 37.347 +Es perfectamente normal actualizar el directorio de trabajo a un 37.348 +conjunto de cambios diferente a la punta actual. Por ejemplo, usted 37.349 +podría desear saber en qué estado se encontraba su proyecto el martes 37.350 +pasado, o podría estar buscando en todos los conjuntos de cambios para 37.351 +saber cuándo se introdujo un fallo. En casos como éstos, la acción 37.352 +natural es actualizar el directorio de trabajo al conjunto de cambios 37.353 +de su interés, y examinar directamente los ficheros en el directorio 37.354 +de trabajo para ver sus contenidos tal como estaban en el momento de 37.355 +hacer la consignación. El efecto que tiene esto se muestra en la 37.356 +figura~\ref{fig:concepts:wdir-pre-branch}. 37.357 + 37.358 +\begin{figure}[ht] 37.359 + \centering 37.360 + \grafix{wdir-pre-branch} 37.361 + \caption{El directorio de trabajo, actualizado a un conjunto de 37.362 + cambios anterior} 37.363 + \label{fig:concepts:wdir-pre-branch} 37.364 +\end{figure} 37.365 + 37.366 +Una vez se ha actualizado el directorio de trabajo a un conjunto de 37.367 +cambios anterior, qué pasa si se hacen cambios, y luego se hace una 37.368 +consignación? Mercurial se comporta en la misma forma que describí 37.369 +anteriormente. Los padres del directorio de trabajo se convierten en 37.370 +los padres del nuevo conjunto de cambios. Este nuevo conjunto de 37.371 +cambios no tiene hijos, así que se convierte en la nueva punta. Y el 37.372 +repositorio tiene ahora dos conjuntos de cambios que no tienen hijos; 37.373 +a éstos los llamamos \emph{frentes}. Usted puede apreciar la 37.374 +estructura que esto crea en la figura~\ref{fig:concepts:wdir-branch}. 37.375 + 37.376 +\begin{figure}[ht] 37.377 + \centering 37.378 + \grafix{wdir-branch} 37.379 + \caption{Después de una consignación hecha mientras se usaba un 37.380 + conjunto de cambios anterior} 37.381 + \label{fig:concepts:wdir-branch} 37.382 +\end{figure} 37.383 + 37.384 +\begin{note} 37.385 + Si usted es nuevo en Mercurial, debería tener en mente un 37.386 + ``error'' común, que es usar el comando \hgcmd{pull} sin ninguna 37.387 + opción. Por defecto, el comando \hgcmd{pull} \emph{no} actualiza 37.388 + el directorio de trabajo, así que usted termina trayendo nuevos 37.389 + conjuntos de cambios a su repositorio, pero el directorio de 37.390 + trabajo sigue usando el mismo conjunto de cambios que tenía antes 37.391 + de jalar. Si usted hace algunos cambios, y luego hace una 37.392 + consignación, estará creando un nuevo frente, porque su directorio 37.393 + de trabajo no es sincronizado a cualquiera que sea la nueva punta. 37.394 + 37.395 + Pongo la palabra ``error'' en comillas porque todo lo que usted 37.396 + debe hacer para rectificar la situación es hacer una fusión 37.397 + (\hgcmd{merge}), y luego una consignación (\hgcmd{commit}). En 37.398 + otras palabras, esto casi nunca tiene consecuencias negativas; 37.399 + sólo sorprende a la gente. Discutiré otras formas de evitar este 37.400 + comportamiento, y porqué Mercurial se comporta de esta forma, 37.401 + inicialmente sorprendente, más adelante. 37.402 +\end{note} 37.403 + 37.404 +\subsection{Fusión de frentes} 37.405 + 37.406 +Cuando usted ejecuta el comando \hgcmd{merge}, Mercurial deja el 37.407 +primer padre del directorio de trabajo intacto, y escribe como segundo 37.408 +padre el conjunto de cambios contra el cual usted está haciendo la 37.409 +fusión, como se muestra en la figura~\ref{fig:concepts:wdir-merge}. 37.410 + 37.411 +\begin{figure}[ht] 37.412 + \centering 37.413 + \grafix{wdir-merge} 37.414 + \caption{Fusión de dos frentes} 37.415 + \label{fig:concepts:wdir-merge} 37.416 +\end{figure} 37.417 + 37.418 +Mercurial también debe modificar el directorio de trabajo, para 37.419 +fusionar los ficheros que él monitorea en los dos conjuntos de 37.420 +cambios. Con algunas simplificaciones, el proceso es el siguiente, por 37.421 +cada fichero en los manifiestos de ambos conjuntos de cambios. 37.422 +\begin{itemize} 37.423 +\item Si ningún conjunto de cambios ha modificado un fichero, no se 37.424 + hace nada con el mismo. 37.425 +\item Si un conjunto de cambios ha modificado un fichero, y el otro no 37.426 + lo ha hecho, se crea una copia del fichero con las modificaciones 37.427 + pertinentes en el directorio de trabajo. 37.428 +\item Si un conjunto de cambios borra un fichero, y el otro no lo ha 37.429 + hecho (o también lo borró), se borra dicho fichero del directorio 37.430 + de trabajo. 37.431 +\item Si un conjunto de cambios ha borrado un fichero, pero el otro lo ha 37.432 + modificado, se le pregunta al usuario qué hacer: conservar el 37.433 + fichero modificado, o borrarlo? 37.434 +\item Si ambos conjuntos de cambios han modificado un fichero, se 37.435 + invoca el programa externo de fusión para definir el nuevo 37.436 + contenido del fichero fusionado. Esto puede requerir interacción 37.437 + directa de parte del usuario. 37.438 +\item Si un conjunto de cambios ha modificado un fichero, y el otro ha 37.439 + renombrado o copiado el mismo, asegurarse de que los cambios sigan 37.440 + al nuevo nombre de fichero. 37.441 +\end{itemize} 37.442 +Hay más detalles---hacer una fusión tiene una gran cantidad de casos 37.443 +especiales---pero éstas son las elecciones más comunes que se ven 37.444 +involucradas en una fusión. Como usted puede ver, muchos de los casos 37.445 +son completamente automáticos, y de hecho la mayoría de las fusiones 37.446 +terminan automáticamente, sin requerir la interacción del usuario para 37.447 +resolver ningún conflicto. 37.448 + 37.449 +Cuando considere qué pasa cuando usted hace una consignación después 37.450 +de una fusión, de nuevo el directorio de trabajo es ``el conjunto de 37.451 +cambios que estoy a punto de consignar''. Una vez termina su trabajo 37.452 +el comando \hgcmd{merge}, el directorio de trabajo tiene dos padre; 37.453 +éstos se convertirán en los padres del nuevo conjunto de cambios. 37.454 + 37.455 +Mercurial le permite hacer múltiples fusiones, pero usted debe 37.456 +consignar los resultados de cada fusión sucesivamente. Esto es 37.457 +necesario porque Mercurial sólo monitorea dos padres, tanto para las 37.458 +revisiones como para los directorios de trabajo. Aunque técnicamente 37.459 +es posible fusionar varios conjuntos de trabajo en una sola operación, 37.460 +la posibilidad de confundir al usuario y crear un desorden terrible en 37.461 +la fusión se hace incontenible de inmediato. 37.462 + 37.463 +\section{Otras características de diseño interesantes} 37.464 + 37.465 +En las secciones anteriores, he tratado de resaltar algunos de los 37.466 +aspectos más importantes del diseño de Mercurial, para mostrar que se 37.467 +presta gran cuidado y atención a la confiabilidad y el desempeño. Sin 37.468 +embargo, la atención a los detalles no para ahí. Hay una cantidad de 37.469 +aspectos de la construcción de Mercurial que encuentro interesantes 37.470 +personalmente. Detallaré unos cuantos de ellos aquí, aparte de los 37.471 +elementos ``importantes'' de arriba, para que, si usted está 37.472 +% TODO the amount of thinking => (la cantidad de) esfuerzo mental 37.473 +interesado, pueda obetener una idea mejor de la cantidad de esfuerzo 37.474 +mental invertido en el diseño de un sistema bien diseñado. 37.475 + 37.476 + 37.477 +\subsection{Compresión ingeniosa} 37.478 + 37.479 +Cuando es adecuado, Mercurial almacenará tanto las instantáneas como 37.480 +los deltas en formato comprimido. Lo hace \emph{tratando} siempre de 37.481 +comprimir una instantánea o delta, y conservando la versión comprimida 37.482 +sólo si es más pequeña que la versión sin compresión. 37.483 + 37.484 +Esto implica que Mercurial hace ``lo correcto'' cuando almacena un 37.485 +fichero cuyo formato original está comprimido, como un fichero 37.486 +\texttt{zip} o una imagen JPEG. Cuando estos tipos de ficheros son 37.487 +comprimidos por segunda vez, el fichero resultante usualmente es más 37.488 +grande que la versión comprimida una sola vez, por lo que Mercurial 37.489 +almacenará el fichero \texttt{zip} o JPEG original. 37.490 + 37.491 +Los deltas entre revisiones de un fichero comprimido usualmente son 37.492 +más grandes que las instantáneas del mismo fichero, y Mercurial de 37.493 +nuevo hace ``lo correcto'' en estos casos. Él encuentra que dicho 37.494 +delta excede el umbral respecto al cual se debería almacenar una 37.495 +instantánea completa del fichero, así que almacena la instantánea, 37.496 +ahorrando espacio de nuevo respecto al enfoque simplista de usar 37.497 +únicamente deltas. 37.498 + 37.499 +\subsubsection{Recompresión de red} 37.500 + 37.501 +Cuando almacena las revisiones en disco, Mercurial usa el algoritmo de 37.502 +compresión ``deflación'' (el mismo usado en el popular formato de 37.503 +fichero \texttt{zip}), que provee una buena velocidad con una tasa de 37.504 +compresión respetable. Sin embargo, cuando se transmiten datos de 37.505 +revisiones a través de una conexión de red, Mercurial descomprime los 37.506 +datos comprimidos de las revisiones. 37.507 + 37.508 +Si la conexión es hecha a través de HTTP, Mercurial recomprime el 37.509 +flujo completo de datos usando un algoritmo de compresión que brinda 37.510 +una mejor tasa de compresión (el algoritmo Burrows-Wheeler del 37.511 +ampliamente usado paquete de compresión \texttt{bzip2}). Esta 37.512 +combinación de algoritmo y compresión del flujo completo de datos 37.513 +(en vez de una revisión a la vez) reduce sustancialmente la cantidad 37.514 +de bytes a transferir, brindando así un mejor desempeño de red sobre 37.515 +casi todo tipo de redes. 37.516 + 37.517 +(Si la conexión se hace sobre \command{ssh}, Mercurial \emph{no} 37.518 +recomprmime el flujo, porque \command{ssh} puede hacer esto por sí 37.519 +mismo.) 37.520 + 37.521 +\subsection{Reordenado de lectura/escritura y atomicidad} 37.522 + 37.523 +Añadir datos al final de un fichero no es todo lo que hace falta para 37.524 +garantizar que un lector no verá una escritura parcial. Si recuerda la 37.525 +figura~\ref{fig:concepts:metadata}, las revisiones en la bitácora de 37.526 +cambios apuntan a revisiones en el manifiesto, y las revisiones en el 37.527 +manifiesto apuntan a revisiones en ficheros de registro. Esta 37.528 +jerarquía es deliberada. 37.529 + 37.530 +Un escritor inicia una transacción al escribir los datos del ficheros 37.531 +del fichero de registro y el manifiesto, y no escribe nada en la 37.532 +bitácora de cambios hasta que dichas escrituras hayan terminado. Un 37.533 +lector empieza leyendo datos de la bitácora de cambios, luego del 37.534 +manifiesto, y finalmente del fichero de registro. 37.535 + 37.536 +%TODO revisar párrafo completo, no me gusta el resultado 37.537 +Como el escritor siempre termina de escribir los datos en el fichero 37.538 +de registro y en el manifiesto antes de escribir a la bitácora de 37.539 +cambios, un lector nunca verá un apuntador a una versión parcialmente 37.540 +escrita de revisiones del manifiesto desde la bitácora de cambios, y 37.541 +nunca leerá un apuntador a una revisión parcialmente escrita del 37.542 +fichero de registro desde el manifiesto. 37.543 + 37.544 +\subsection{Acceso concurrente} 37.545 + 37.546 +El reordenado de lectura/escritura y la atomicidad garantizan que 37.547 +Mercurial nunca necesita \emph{bloquear} un repositorio cuando está 37.548 +leyendo datos, aún si se está escribiendo al repositorio mientras se 37.549 +hace la lectura. Esto tiene un gran efecto en la escalabilidad; usted 37.550 +puede tener cualquier cantidad de procesos Mercurial leyendo datos de 37.551 +un repositorio de manera segura al mismo tiempo, sin importar si se 37.552 +está escribiendo al mismo o no. 37.553 + 37.554 +La naturaleza carente de bloqueos de la lectura significa que si usted 37.555 +está compartiendo un repositorio en un sistema multiusuario, no 37.556 +necesita dar a los usuarios locales permisos de \emph{escritura} a su 37.557 +repositorio para que ellos puedan clonarlo o jalar cambios; sólo 37.558 +necesitan permisos de \emph{lectura}. (Esta \emph{no} es una 37.559 +%TODO signo de admiración de apertura 37.560 +característica común entre los sistemas de control de revisiones, así 37.561 +que no la dé por hecha! Muchos de ellos requieren que los lectores 37.562 +sean capaces de bloquear el repositorio antes de poder leerlo, y esto 37.563 +requiere acceso de escritura en al menos un directorio, lo que por 37.564 +supuesto se convierte en una fuente de todo tipo de problemas 37.565 +administrativos y de seguridad bastante molestos.) 37.566 + 37.567 +Mercurial usar bloqueos para asegurarse de que sólo un proceso pueda 37.568 +escribir a un repositorio al mismo tiempo (el mecanismo de bloqueo es 37.569 +seguro incluso sobre sistemas de ficheros notoriamente hostiles al 37.570 +bloqueo, como NFS). Si un repositorio está bloqueado, los escritores 37.571 +esperarán un buen rato para revisar si el repositorio ya ha sido 37.572 +desbloqueado, pero si el repositorio sique bloqueado por mucho tiempo, 37.573 +el proceso que intenta escribir fallará por tiempo de espera máximo. 37.574 +Esto significa que sus guiones automáticos diarios no se quedarán 37.575 +esperando para siempre, apilándose si el sistema se cayó sin que nadie 37.576 +se diera cuenta, por ejemplo. (Sí, el tiempo de espera máximo es 37.577 +configurable, de cero a infinito). 37.578 + 37.579 + 37.580 +\subsubsection{Acceso seguro al estado de directorio} 37.581 + 37.582 +Al igual que con los datos de revisión, Mercurial no requiere un 37.583 +bloqueo para leer el fichero de estado de directorio; sí se usa un 37.584 +bloqueo para escribir a él. Para evitar la posibilidad de leer una 37.585 +copia parcialmente escrita del fichero de estado de directorio, 37.586 +Mercurial escribe a un fichero con un nombre único en el mismo 37.587 +directorio del fichero de estado de directorio, y luego renombra 37.588 +atómicamente este fichero temporal a \filename{dirstate}\ndt{Estado de 37.589 +directorio.}. Así se garantiza que el fichero llamado 37.590 +\filename{dirstate} esté completo, y no parcialmente escrito. 37.591 + 37.592 +\subsection{Evitar movimientos de brazo} 37.593 + 37.594 +Un aspecto crítico para el desempeño de Mercurial es evitar los 37.595 +movimientos del brazo de lectura del disco duro, ya que cualquier 37.596 +movimiento de brazo es mucho más costoso que incluso una operación de 37.597 +lectura relativamente grande. 37.598 + 37.599 +Es por esto que, por ejemplo, el estado de directorio es almacenado 37.600 +como un solo fichero. Si hubiera un estado de directorio por cada 37.601 +directorio que Mercurial monitorea, el disco haría un movimiento de 37.602 +brazo por cada directorio. En cambio, Mercurial lee el estado de 37.603 +directorio completo en un solo paso. 37.604 + 37.605 +Mercurial también usa un esquema de ``copiar al escribir'' cuando 37.606 +clona un repositorio en un mismo medio de almacenamiento local. En vez 37.607 +de copiar cada fichero de revlog del repositorio viejo al nuevo, se 37.608 +crea un ``enlace duro'', que es una manera sucinta de decir 37.609 +``estos dos nombres apuntan al mismo fichero''. Cuando Mercurial está 37.610 +a punto de escribir a uno de los ficheros de revlog, revisa si la 37.611 +cantidad de nombres apuntando al fichero es de más de uno. Si lo es, 37.612 +más de un repositorio está usando el fichero, así que Mercurial hace 37.613 +una nueva copia del fichero, privada para este repositorio. 37.614 + 37.615 +Algunos desarrolladores de control de revisiones han indicado que la 37.616 +idea de hacer una copia privada completa de un fichero no es eficiente 37.617 +desde el punto de vista de almacenamiento. Aunque esto es cierto, el 37.618 +almacenamiento es barato, y este método brinda el máximo rendimiento 37.619 +al tiempo que delega la mayor parte del trabajo de manejo de ficheros 37.620 +al sistema operativo. Un esquema alternativo seguramente reduciría el 37.621 +desempeño y aumentaría la complejidad del software, cada uno de los 37.622 +cuales es mucho más importante para la ``sensación'' que se tiene del 37.623 +software en el trabajo día a día. 37.624 + 37.625 +\subsection{Otros contenidos del estado de directorio} 37.626 + 37.627 +Debido a que Mercurial no lo fuerza a indicar si usted está 37.628 +modificando un fichero, se usa el estado de directorio para almacenar 37.629 +información extra para poder determinar efecientemente si usted ha 37.630 +modificado un fichero. Por cada fichero en el directorio de trabajo, 37.631 +se almacena el momento en que Mercurial modificó por última vez el 37.632 +fichero, y el tamaño del fichero en ese momento. 37.633 + 37.634 +Cuando usted añade (\hgcmd{add}), remueve (\hgcmd{remove}), renombra 37.635 +(\hgcmd{rename}) o copia (\hgcmd{copy}) ficheros, Mercurial actualiza 37.636 +el estado de directorio para saber qué hacer con dichos ficheros 37.637 +cuando usted haga la consignación. 37.638 + 37.639 +Cuando Mercurial está revisando el estado de los ficheros en el 37.640 +directorio de trabajo, revisa primero la fecha de modificación del 37.641 +fichero. Si no ha cambiado, el fichero no ha sido modificado. Si el 37.642 +tamaño del fichero ha cambiado, el fichero ha sido modificado. Sólo en 37.643 +el caso en que el tiempo de modificación ha cambiado, pero el tamaño 37.644 +no, es necesario leer el contenido del fichero para revisar si ha 37.645 +cambiado. Almacenar estos pocos datos reduce dramáticamente la 37.646 +cantidad de datos que Mercurial debe leer, lo que brinda una mejora en 37.647 +el rendimiento grande, comparado con otros sistemas de control de 37.648 +revisiones. 37.649 + 37.650 +%%% Local Variables: 37.651 +%%% mode: latex 37.652 +%%% TeX-master: "00book" 37.653 +%%% End:
38.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 38.2 +++ b/es/daily.tex Thu Jan 29 22:00:07 2009 -0800 38.3 @@ -0,0 +1,404 @@ 38.4 +\chapter{Mercurial día a día} 38.5 +\label{chap:daily} 38.6 + 38.7 +\section{Cómo indicarle a Mercurial qué ficheros seguir} 38.8 + 38.9 +Mercurial no trabaja con ficheros en su repositorio a menos que usted 38.10 +se lo indique explícitamente. La orden \hgcmd{status} le mostrará 38.11 +cuáles ficheros son desconocidos para Mercurial; se emplea un 38.12 +``\texttt{?}'' para mostrar tales ficheros. 38.13 + 38.14 +Para indicarle a Mercurial que tenga en cuenta un fichero, emplee la 38.15 +orden \hgcmd{add}. Una vez que haya adicionado el fichero, la línea 38.16 +referente al fichero al aplicar la orden \hgcmd{status} para tal 38.17 +fichero cambia de ``\texttt{?}'' a ``\texttt{A}''. 38.18 +\interaction{daily.files.add} 38.19 + 38.20 +Después de invocar \hgcmd{commit}, los ficheros que haya adicionado 38.21 +antes de consignar no se listarán en la salida de \hgcmd{status}. La 38.22 +razón para esto es que \hgcmd{status} solamente le muestra aquellos 38.23 +ficheros ``interesantes'' ---~los que usted haya modificado o a aquellos 38.24 +sobre los que usted haya indicado a Mercurial hacer algo--- de forma 38.25 +predeterminada. Si tiene un repositorio que contiene miles de 38.26 +ficheros, rara vez deseará saber cuáles de ellos están siendo 38.27 +seguidos por Mercurial, pero que no han cambiado. (De todas maneras, 38.28 +puede obtener tal información; más adelante hablaremos de ello.) 38.29 + 38.30 + 38.31 +Cuando usted añade un fichero, Mercurial no hace nada con él inmediatamente. 38.32 +En cambio, tomará una instantánea del estado del fichero la próxima vez 38.33 +que usted consigne. Continuará haciendo seguimiento a los cambios que 38.34 +haga sobre el fichero cada vez que consigne, hasta que usted lo elimine. 38.35 + 38.36 +\subsection{Nombramiento explícito e implícito de ficheros} 38.37 + 38.38 +Mercurial tiene un comportamiento útil en el cual si a una orden, 38.39 +le pasa el nombre de un directorio, todas las órdenes lo interpretarán como 38.40 +``Deseo operar en cada fichero de este directorio y sus 38.41 +subdirectorios''. 38.42 +\interaction{daily.files.add-dir} 38.43 +Tenga en cuenta que en este ejemplo Mercurial imprimió los nombres de 38.44 +los ficheros que se adicionaron, mientras que no lo hizo en el ejemplo 38.45 +anterior cuando adicionamos el fichero con nombre \filename{a}. 38.46 + 38.47 +En el último caso hicimos explícito el nombre del fichero que 38.48 +deseábamos adicionar en la línea de órdenes, y Mercurial asume en 38.49 +tales casos que usted sabe lo que está haciendo y no imprime 38.50 +información alguna. 38.51 + 38.52 +Cuando hacemos \emph{implícitos} los nombres de los ficheros dando el 38.53 +nombre de un directorio, Mercurial efectúa el paso extra de imprimir 38.54 +el nombre de cada fichero con el que va a hacer algo. Esto para 38.55 +aclarar lo que está sucediendo, y reducir en lo posible una sorpresa 38.56 +silenciosa pero fatal. Este comportamiento es común a la mayoría de 38.57 +órdenes en Mercurial. 38.58 + 38.59 +\subsection{Nota al margen: Mercurial trata ficheros, no directorios} 38.60 + 38.61 +Mercurial no da seguimiento a la información de los directorios. En 38.62 +lugar de eso tiene en cuenta las rutas de los ficheros. Antes de 38.63 +crear un fichero, primero crea todos los directorios que hagan falta 38.64 +para completar la ruta del mismo. Después de borrar un fichero, 38.65 +borra todos los directorios vacíos que estuvieran en la ruta del 38.66 +fichero borrado. Suena como una diferencia trivial, pero tiene una 38.67 +consecuencia práctica menor: no es posible representar un directorio 38.68 +completamente vacío en Mercurial. 38.69 + 38.70 +Los directorios vacíos rara vez son útiles, y hay soluciones 38.71 +alternativas no intrusivas que usted puede emplear para obtener el efecto 38.72 +apropiado. Los desarrolladores de Mercurial pensaron que la 38.73 +complejidad necesaria para administrar directorios vacíos no valía la 38.74 +pena frente al beneficio limitado que esta característica podría traer. 38.75 + 38.76 +Si necesita un directorio vacío en su repositorio, hay algunas formas 38.77 +de lograrlo. Una es crear un directorio, después hacer \hgcmd{add} a 38.78 +un fichero ``oculto'' dentro de ese directorio. En sistemas tipo 38.79 +Unix, cualquier fichero cuyo nombre comience con un punto 38.80 +(``\texttt{.}'') es tratado como oculto por la mayoría de 38.81 +comandos y herramientas GUI. Esta aproximación se ilustra en la figura~\ref{ex:daily:hidden}. 38.82 + 38.83 +\begin{figure}[ht] 38.84 + \interaction{daily.files.hidden} 38.85 + \caption{Simular un directorio vacío con un fichero oculto} 38.86 + \label{ex:daily:hidden} 38.87 +\end{figure} 38.88 + 38.89 +Otra forma de abordar la necesidad de un directorio vacío es 38.90 +simplemente crear uno en sus guiones de construcción antes de que lo 38.91 +necesiten. 38.92 + 38.93 +\section{Cómo dejar de hacer seguimiento a un fichero} 38.94 + 38.95 +Si decide que un fichero no pertenece a su repositorio, use la orden 38.96 +\hgcmd{remove}; se borrará el fichero y le indicará a Mercurial que 38.97 +deje de hacerle seguimiento. Los ficheros eliminados se representan 38.98 +con ``\texttt{R}'' al usar \hgcmd{status}. 38.99 +\interaction{daily.files.remove} 38.100 + 38.101 +Después de hacer \hgcmd{remove} a un fichero, Mercurial dejará de 38.102 +hacer seguimiento al mismo, incluso si recrea el fichero con el mismo 38.103 +nombre en su directorio de trabajo. Si decide recrear un fichero con 38.104 +el mismo nombre y desea que Mercurial le haga seguimiento, basta con 38.105 +hacerle \hgcmd{add}. Mercurial sabrá que el fichero recientemente 38.106 +adicionado no está relacionado con el fichero anterior que tenía el 38.107 +mismo nombre. 38.108 + 38.109 +\subsection{Al eliminar un fichero no se afecta su historial} 38.110 + 38.111 +Es preciso tener en cuenta que eliminar un fichero tiene sólo dos 38.112 +efectos. 38.113 +\begin{itemize} 38.114 +\item Se elimina la versión actual del fichero del directorio de 38.115 +trabajo. 38.116 +\item Mercurial deja de hacer seguimiento a los cambios del fichero 38.117 + desde la próxima consignación. 38.118 +\end{itemize} 38.119 +Al eliminar un fichero \emph{no} se altera de ninguna manera el 38.120 +\emph{historial} del mismo. 38.121 + 38.122 +Si actualiza su directorio de trabajo a un conjunto de cambios en el 38.123 +cual el fichero que eliminó aún era tenido en cuenta, éste reaparecerá en 38.124 +el directorio de trabajo, con los contenidos que este tenía cuando se 38.125 +consignó tal conjunto de cambios. Si usted actualiza el directorio de 38.126 +trabajo a un conjunto de cambios posterior en el cual el fichero había 38.127 +sido eliminado, Mercurial lo eliminará de nuevo del directorio de 38.128 +trabajo. 38.129 + 38.130 +\subsection{Ficheros perdidos} 38.131 + 38.132 +Mercurial considera como \emph{perdido} un fichero que usted borró, 38.133 +pero para el que no se usó \hgcmd{remove}. Los ficheros perdidos se 38.134 +representan con ``\texttt{!}'' al visualizar \hgcmd{status}. 38.135 +Las órdenes de Mercurial generalmente no harán nada con los ficheros 38.136 +perdidos. 38.137 +\interaction{daily.files.missing} 38.138 + 38.139 +Si su repositorio contiene un fichero que \hgcmd{status} reporta como 38.140 +perdido, y desea que el mismo se vaya, se puede usar 38.141 +\hgcmdargs{remove}{\hgopt{remove}{--after}} posteriormente para 38.142 +indicarle a Mercurial que usted deseaba borrar tal fichero. 38.143 +\interaction{daily.files.remove-after} 38.144 + 38.145 +Por otro lado, si borró un fichero perdido por accidente, puede usar 38.146 +\hgcmdargs{revert}{\emph{nombre de fichero}} para recuperar el 38.147 +fichero. Reaparecerá, sin modificaciones. 38.148 +\interaction{daily.files.recover-missing} 38.149 + 38.150 +\subsection{Nota al margen: ¿Por qué decirle explícitamente a Mercurial 38.151 + que elimine un fichero?} 38.152 + 38.153 +Es posible que se haya preguntado por qué Mercurial exige que usted le 38.154 +indique explícitamente que está borrando un fichero. Al principio del 38.155 +desarrollo de Mercurial, este permitía que usted borrara el fichero 38.156 +sin más; Mercurial se daría cuenta de la ausencia del fichero 38.157 +automáticamente después de la ejecución de \hgcmd{commit}, y dejaría de 38.158 +hacer seguimiento al fichero. En la práctica, resultaba muy sencillo 38.159 +borrar un fichero accidentalmente sin darse cuenta. 38.160 + 38.161 +\subsection{Atajo útil---agregar y eliminar ficheros en un solo paso} 38.162 + 38.163 +Mercurial ofrece una orden combinada, \hgcmd{addremove}, que agrega 38.164 +los ficheros que no tienen seguimiento y marca los ficheros faltantes 38.165 +como eliminados. 38.166 +\interaction{daily.files.addremove} 38.167 +La orden \hgcmd{commit} se puede usar con la opción \hgopt{commit}{-A} 38.168 +que aplica el mismo agregar-eliminar, seguido inmediatamente de una 38.169 +consignación. 38.170 +\interaction{daily.files.commit-addremove} 38.171 + 38.172 +\section{Copiar ficheros} 38.173 + 38.174 +Mercurial ofrece la orden \hgcmd{copy} para hacer una copia nueva de 38.175 +un fichero. Cuando se copia un fichero con esta orden, Mercurial 38.176 +lleva un registro indicando que el nuevo fichero es una copia del 38.177 +fichero original. Los ficheros copiados se tratan de forma especial cuando 38.178 +usted hace una fusión con el trabajo de alguien más. 38.179 + 38.180 +\subsection{Resultados de copiar un fichero durante una fusión} 38.181 + 38.182 +Durante una fusión los cambios ``siguen'' una copia. Para ilustrar 38.183 +lo que esto significa, haremos un ejemplo. Comenzaremos con el mini 38.184 +repositorio usual que contiene un solo fichero 38.185 +\interaction{daily.copy.init} 38.186 +Debemos hacer algo de trabajo en paralelo, de forma que tengamos algo para 38.187 +fusionar. Aquí clonamos el repositorio. 38.188 +\interaction{daily.copy.clone} 38.189 +De vuelta en el repositorio inicial, usemos la orden \hgcmd{copy} para hacer 38.190 +una copia del primer fichero que creamos. 38.191 +\interaction{daily.copy.copy} 38.192 + 38.193 +Si vemos la salida de la orden \hgcmd{status}, el fichero copiado luce 38.194 +tal como un fichero que se ha añadido normalmente. 38.195 +\interaction{daily.copy.status} 38.196 +Pero si usamos la opción \hgopt{status}{-C} de la orden 38.197 +\hgcmd{status}, se imprimirá otra línea: el fichero \emph{desde} el 38.198 +cual fue copiado nuestro fichero recién añadido. 38.199 +\interaction{daily.copy.status-copy} 38.200 + 38.201 +Ahora, en el repositorio que clonamos, hagamos un cambio en 38.202 +paralelo. Adicionaremos una línea de contenido al fichero original que 38.203 +creamos. 38.204 +\interaction{daily.copy.other} 38.205 +Hemos modificado el fichero \filename{file} en este 38.206 +repositorio. Cuando jalemos los cambios del primer repositorio y 38.207 +fusionemos las dos cabezas, Mercurial propagará los cambios que hemos 38.208 +hecho localmente en \filename{file} a su copia, \filename{new-file}. 38.209 +\interaction{daily.copy.merge} 38.210 + 38.211 +\subsection{¿Por qué los cambios se reflejan en las copias?} 38.212 +\label{sec:daily:why-copy} 38.213 + 38.214 +Este comportamiento de cambios en ficheros que se propagan a las 38.215 +copias de los ficheros parecería esotérico, pero en la mayoría de 38.216 +casos es absolutamente deseable. 38.217 +Es indispensable recordar que esta propagación \emph{solamente} sucede 38.218 +cuando fusionamos. Por lo tanto si sobre un fichero se usa 38.219 +\hgcmd{copy}, y se modifica el fichero original durante el curso 38.220 +normal de su trabajo, nada pasará. 38.221 + 38.222 +Lo segundo a tener en cuenta es que las modificaciones solamente se 38.223 +propagarán en las copias únicamente si los repositorios de los cuales 38.224 +está jalando los cambios \emph{no saben} de la copia. 38.225 + 38.226 +Explicaremos a continuación la razón de este comportamiento de 38.227 +Mercurial. Digamos que yo he aplicado un arreglo de un fallo importante a un 38.228 +fichero fuente y consigné los cambios. Por otro lado, usted decidió hacer 38.229 +\hgcmd{copy} sobre el fichero en su repositorio, sin saber acerca del 38.230 +fallo o sin ver el arreglo, y ha comenzado a trabajar sobre su copia 38.231 +del fichero. 38.232 + 38.233 +Si jala y fusiona mis cambios y Mercurial \emph{no hubiera} propagado 38.234 +los cambios en las copias, su fichero fuente tendría el fallo, a menos 38.235 +que usted haya recordado propagar el arreglo del fallo a mano, el 38.236 +mismo \emph{permanecería} en su copia del fichero. 38.237 + 38.238 +Mercurial previene esta clase de problemas, gracias a la propagación 38.239 +automática del cambio que arregló el fallo del fichero original. Hasta 38.240 +donde sé, Mercurial es el \emph{único} sistema de control de 38.241 +revisiones que propaga los cambios en las copias de esta forma. 38.242 + 38.243 +Cuando su historial de cambios tiene un registro de la copia y la 38.244 +subsecuente fusión, usualmente no es necesario propagar los cambios el 38.245 +fichero original a las copias del mismo, y por esta razón Mercurial 38.246 +propaga únicamente los cambios en las copias hasta este punto y no más 38.247 +allá. 38.248 + 38.249 + 38.250 +\subsection{Cómo hacer que los cambios \emph{no} sigan a la copia?} 38.251 + 38.252 +Si por algún motivo usted decide que esta característica de 38.253 +propagación automática de cambios en las copias no es para usted, 38.254 +simplemente use 38.255 +la orden usual de su sistema para copiar ficheros (en sistemas tipo 38.256 +Unix, es \command{cp}), y posteriormente use \hgcmd{add} sobre la nueva 38.257 +copia hecha a mano. Antes de hacerlo, de todas maneras, relea la 38.258 +sección~\ref{sec:daily:why-copy}, y tome una decisión asegurándose que 38.259 +este comportamiento no es el apropiado para su caso específico. 38.260 + 38.261 +\subsection{Comportamiento de la orden \hgcmd{copy}} 38.262 + 38.263 +Cuando usa la orden \hgcmd{copy}, Mercurial hace una copia de cada 38.264 +fichero fuente tal como se encuentra en el directorio actual. Esto 38.265 +significa que si usted hace 38.266 +modificaciones a un fichero, y le aplica \hgcmd{copy} sin haber 38.267 +consignado primero los cambios, la nueva copia contendrá también las 38.268 +modificaciones que haya hecho hasta ese punto. (Este comportamiento me 38.269 +parece poco intuitivo, y por tal motivo lo menciono.) 38.270 + 38.271 +La orden \hgcmd{copy} actúa de forma parecida a la orden \command{cp} 38.272 +de Unix (puede usar el alias \hgcmd{cp} si le es más cómodo). El 38.273 +último argumento es el \emph{destino}, y todos los argumentos previos 38.274 +son las \emph{fuentes}. Si solamente indica un fichero como la 38.275 +fuente, y el destino no existe, se crea un fichero nuevo con ese nombre. 38.276 +\interaction{daily.copy.simple} 38.277 +Si el destino es un directorio, Mercurial copia las fuentes en éste. 38.278 +\interaction{daily.copy.dir-dest} 38.279 +La copia de un directorio es recursiva, y preserva la estructura del 38.280 +directorio fuente. 38.281 +\interaction{daily.copy.dir-src} 38.282 +Si tanto la fuente como el destino son directorios, la estructura de 38.283 +la fuente se recrea en el directorio destino. 38.284 +\interaction{daily.copy.dir-src-dest} 38.285 + 38.286 +De la misma forma que la orden \hgcmd{rename}, si copia un fichero 38.287 +manualmente y desea que Mercurial sepa que ha copiado un fichero, 38.288 +basta con aplicar la opción \hgopt{copy}{--after} a la orden 38.289 +\hgcmd{copy}. 38.290 +\interaction{daily.copy.after} 38.291 + 38.292 +\section{Renombrar ficheros} 38.293 + 38.294 +La necesidad de renombrar un fichero es más común que hacer una copia 38.295 +del mismo. La razón por la cual discutí la orden \hgcmd{copy} antes 38.296 +de hablar acerca de cambiar el nombre de los ficheros, es que 38.297 +Mercurial trata el renombrar un fichero de la misma forma que una 38.298 +copia. Por lo tanto, saber lo que hace Mercurial cuando usted copia 38.299 +un fichero le indica qué esperar cuando renombra un fichero. 38.300 + 38.301 +Cuando usa la orden \hgcmd{rename}, Mercurial hace una copia de cada 38.302 +fichero fuente, lo borra y lo marca como fichero eliminado. 38.303 +\interaction{daily.rename.rename} 38.304 +La orden \hgcmd{status} muestra la nueva copia del fichero como 38.305 +añadida y el fichero inicial de la copia, como eliminado. 38.306 +\interaction{daily.rename.status} 38.307 +De la misma forma en que se usa la orden \hgcmd{copy}, debemos usar la 38.308 +opción \hgopt{status}{-C} de la orden \hgcmd{status} para verificar 38.309 +que el fichero añadido realmente comienza a ser seguido por Mercurial 38.310 +como una copia del fichero original, ahora eliminado. 38.311 +\interaction{daily.rename.status-copy} 38.312 + 38.313 +Igual que con \hgcmd{remove} y \hgcmd{copy}, puede indicársele a 38.314 +Mercurial acerca de un renombramiento inmediato con la opción 38.315 +\hgopt{rename}{--after}. El comportamiento de la orden 38.316 +\hgcmd{rename} y las opciones que acepta, son similares a la orden 38.317 +\hgcmd{copy} en casi todo. 38.318 + 38.319 +\subsection{Renombrar ficheros y fusionar cambios} 38.320 + 38.321 +Dado que el renombrado de Mercurial se implementa como un 38.322 +copiar-y-eliminar, la misma propagación de cambios ocurre cuando usted 38.323 +fusiona después de renombrar como después de hacer una copia. 38.324 + 38.325 +Si yo modifico un fichero y usted lo renombra a un nuevo fichero, y 38.326 +posteriormente fusionamos nuestros respectivos cambios, mi 38.327 +modificación al fichero bajo su nombre original se propagará en el 38.328 +fichero con el nuevo nombre. (Es lo que se esperaría que ``simplemente 38.329 +funcione,'' 38.330 +pero, no todos los sistemas de control de revisiones hacen esto.) 38.331 + 38.332 +Aunque el hecho de que los cambios sigan la copia es una característica 38.333 +respecto a la cual usted puede estar de acuerdo y decir ``si, puede 38.334 +ser útil,'' debería ser claro 38.335 +que el seguimiento de cambios de un renombramiento es definitivamente 38.336 +importante. Sin esto, sería muy sencillo que los cambios se 38.337 +quedaran atrás cuando los ficheros se renombran. 38.338 + 38.339 +\subsection{Cambios de nombre divergentes y fusión} 38.340 + 38.341 +El caso de renombramiento con nombres divergentes ocurre cuando dos 38.342 +desarrolladores comienzan con un fichero---llamémoslo 38.343 +\filename{foo}---en sus repositorios respectivos. 38.344 + 38.345 +\interaction{rename.divergent.clone} 38.346 +%TODO we must either change the example's names, and these names, or 38.347 +%use the original names. as of now, we keep the old names 38.348 +Anne renombra el fichero a \filename{bar}. 38.349 +\interaction{rename.divergent.rename.anne} 38.350 +Mientras que Bob lo renombra como \filename{quux}. 38.351 +\interaction{rename.divergent.rename.bob} 38.352 + 38.353 +Veo esto como un conflicto porque cada desarrollador ha expresado 38.354 +intenciones diferentes acerca de cómo considera debería haberse 38.355 +nombrado el fichero. 38.356 + 38.357 +¿Qué cree que debería pasar cuando fusionen su trabajo? 38.358 +El comportamiento de Mercurial es que siempre preserva \emph{ambos} 38.359 +nombres cuando fusiona los conjuntos de cambios que contienen nombres 38.360 +divergentes. 38.361 +%TODO traducir texto interaccion 38.362 +\interaction{rename.divergent.merge} 38.363 + 38.364 +Tenga en cuenta que Mercurial le advierte acerca de nombres 38.365 +divergentes, pero deja que usted decida qué hacer con la divergencia 38.366 +después de la fusión. 38.367 + 38.368 +\subsection{Cambios de nombre convergentes y fusión} 38.369 + 38.370 +Otra clase de conflicto al cambiar el nombre de ficheros ocurre cuando dos 38.371 +personas eligen renombrar diferentes ficheros \emph{fuente} al mismo 38.372 +\emph{destino}. En este caso Mercurial aplica su maquinaria de fusión 38.373 +usual, y le permite a usted guiar la situación a una resolución adecuada. 38.374 + 38.375 +\subsection{Otros casos límite relacionados con renombramientos} 38.376 + 38.377 +Mercurial tiene un fallo de mucho tiempo en el cual no es capaz de 38.378 +fusionar cuando por un lado hay un fichero con un nombre dado, 38.379 +mientras que en otro hay un directorio con el mismo nombre. Esto está 38.380 +documentado como~\bug{29}. 38.381 +\interaction{issue29.go} 38.382 + 38.383 +\section{Recuperarse de equivocaciones} 38.384 + 38.385 +Mercurial tiene unas órdenes poderosas que le ayudarán a recuperarse 38.386 +de equivocaciones comunes. 38.387 + 38.388 +La orden \hgcmd{revert} le permite deshacer cambios que haya hecho a 38.389 +su directorio de trabajo. Por ejemplo, si aplicó \hgcmd{add} a un 38.390 +fichero por accidente, ejecute \hgcmd{revert} con el nombre del 38.391 +fichero que añadió, y en tanto que el fichero no haya sido tocado de 38.392 +forma alguna, no será adicionado, ni seguido por Mercurial. También 38.393 +puede usar \hgcmd{revert} para deshacerse de cambios erróneos a un 38.394 +fichero. 38.395 + 38.396 +Tenga en cuenta que la orden \hgcmd{revert} se usa para cambios que no 38.397 +han sido consignados. Cuando haya consignado un cambio, si decide que 38.398 +era un error, puede hacer algo todavía, pero sus opciones pueden estar 38.399 +más limitadas. 38.400 + 38.401 +Para obtener información acerca de la orden \hgcmd{revert} y detalles 38.402 +de cómo tratar con cambios consignados, vea el capítulo~\ref{chap:undo}. 38.403 + 38.404 +%%% Local Variables: 38.405 +%%% mode: latex 38.406 +%%% TeX-master: "00book" 38.407 +%%% End:
39.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 39.2 +++ b/es/examples/backout Thu Jan 29 22:00:07 2009 -0800 39.3 @@ -0,0 +1,83 @@ 39.4 +#!/bin/bash 39.5 + 39.6 +# We have to fake the merges here, because they cause conflicts with 39.7 +# three-way command-line merge, and kdiff3 may not be available. 39.8 + 39.9 +export HGMERGE=$(mktemp) 39.10 +echo '#!/bin/sh' >> $HGMERGE 39.11 +echo 'echo first change > "$1"' >> $HGMERGE 39.12 +echo 'echo third change >> "$1"' >> $HGMERGE 39.13 +chmod 700 $HGMERGE 39.14 + 39.15 +#$ name: init 39.16 + 39.17 +hg init myrepo 39.18 +cd myrepo 39.19 +echo first change >> myfile 39.20 +hg add myfile 39.21 +hg commit -m 'first change' 39.22 +echo second change >> myfile 39.23 +hg commit -m 'second change' 39.24 + 39.25 +#$ name: simple 39.26 + 39.27 +hg backout -m 'back out second change' tip 39.28 +cat myfile 39.29 + 39.30 +#$ name: simple.log 39.31 +#$ ignore: \s+200[78]-.* 39.32 + 39.33 +hg log --style compact 39.34 + 39.35 +#$ name: non-tip.clone 39.36 + 39.37 +cd .. 39.38 +hg clone -r1 myrepo non-tip-repo 39.39 +cd non-tip-repo 39.40 + 39.41 +#$ name: non-tip.backout 39.42 + 39.43 +echo third change >> myfile 39.44 +hg commit -m 'third change' 39.45 +hg backout --merge -m 'back out second change' 1 39.46 + 39.47 +#$ name: non-tip.cat 39.48 +cat myfile 39.49 + 39.50 +#$ name: manual.clone 39.51 + 39.52 +cd .. 39.53 +hg clone -r1 myrepo newrepo 39.54 +cd newrepo 39.55 + 39.56 +#$ name: manual.backout 39.57 + 39.58 +echo third change >> myfile 39.59 +hg commit -m 'third change' 39.60 +hg backout -m 'back out second change' 1 39.61 + 39.62 +#$ name: manual.log 39.63 + 39.64 +hg log --style compact 39.65 + 39.66 +#$ name: manual.parents 39.67 + 39.68 +hg parents 39.69 + 39.70 +#$ name: manual.heads 39.71 + 39.72 +hg heads 39.73 + 39.74 +#$ name: manual.cat 39.75 + 39.76 +cat myfile 39.77 + 39.78 +#$ name: manual.merge 39.79 + 39.80 +hg merge 39.81 +hg commit -m 'merged backout with previous tip' 39.82 +cat myfile 39.83 + 39.84 +#$ name: 39.85 + 39.86 +rm $HGMERGE
40.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 40.2 +++ b/es/examples/bisect Thu Jan 29 22:00:07 2009 -0800 40.3 @@ -0,0 +1,96 @@ 40.4 +#!/bin/bash 40.5 + 40.6 +if hg -v | head -1 | grep -e "version 0.*" 40.7 +then 40.8 +#On mercurial 1.0 and later bisect is a builtin 40.9 +echo '[extensions]' >> $HGRC 40.10 +echo 'hbisect =' >> $HGRC 40.11 +fi 40.12 + 40.13 +# XXX There's some kind of horrible nondeterminism in the execution of 40.14 +# bisect at the moment. Ugh. 40.15 + 40.16 +#$ ignore: .* 40.17 + 40.18 +#$ name: init 40.19 + 40.20 +hg init mybug 40.21 +cd mybug 40.22 + 40.23 +#$ name: commits 40.24 + 40.25 +buggy_change=22 40.26 + 40.27 +for (( i = 0; i < 35; i++ )); do 40.28 + if [[ $i = $buggy_change ]]; then 40.29 + echo 'i have a gub' > myfile$i 40.30 + hg commit -q -A -m 'buggy changeset' 40.31 + else 40.32 + echo 'nothing to see here, move along' > myfile$i 40.33 + hg commit -q -A -m 'normal changeset' 40.34 + fi 40.35 +done 40.36 + 40.37 +#$ name: help 40.38 + 40.39 +hg help bisect 40.40 + 40.41 +#$ name: search.init 40.42 + 40.43 +if hg -v | head -1 | grep -e "version 0.*" 40.44 +then 40.45 +#On mercurial 1.0 --init disappeared 40.46 +hg bisect --init 40.47 +fi 40.48 + 40.49 +#$ name: search.bad-init 40.50 + 40.51 +hg bisect --bad 40.52 + 40.53 +#$ name: search.good-init 40.54 + 40.55 +hg bisect --good 10 40.56 + 40.57 +#$ name: search.step1 40.58 + 40.59 +if grep -q 'i have a gub' * 40.60 +then 40.61 + result=bad 40.62 +else 40.63 + result=good 40.64 +fi 40.65 + 40.66 +echo this revision is $result 40.67 +hg bisect --$result 40.68 + 40.69 +#$ name: search.mytest 40.70 + 40.71 +mytest() { 40.72 + if grep -q 'i have a gub' * 40.73 + then 40.74 + result=bad 40.75 + else 40.76 + result=good 40.77 + fi 40.78 + 40.79 + echo this revision is $result 40.80 + hg bisect --$result 40.81 +} 40.82 + 40.83 +#$ name: search.step2 40.84 + 40.85 +mytest 40.86 + 40.87 +#$ name: search.rest 40.88 + 40.89 +mytest 40.90 +mytest 40.91 +mytest 40.92 + 40.93 +#$ name: search.reset 40.94 + 40.95 +hg bisect --reset 40.96 + 40.97 +#$ name: 40.98 + 40.99 +exit 0
41.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 41.2 +++ b/es/examples/branch-named Thu Jan 29 22:00:07 2009 -0800 41.3 @@ -0,0 +1,73 @@ 41.4 +#!/bin/bash 41.5 + 41.6 +hg init a 41.7 +cd a 41.8 +echo hello > myfile 41.9 +hg commit -A -m 'Initial commit' 41.10 + 41.11 +#$ name: branches 41.12 + 41.13 +hg tip 41.14 +hg branches 41.15 + 41.16 +#$ name: branch 41.17 + 41.18 +hg branch 41.19 + 41.20 +#$ name: create 41.21 + 41.22 +hg branch foo 41.23 +hg branch 41.24 + 41.25 +#$ name: status 41.26 + 41.27 +hg status 41.28 +hg tip 41.29 + 41.30 +#$ name: commit 41.31 + 41.32 +echo 'hello again' >> myfile 41.33 +hg commit -m 'Second commit' 41.34 +hg tip 41.35 + 41.36 +#$ name: rebranch 41.37 + 41.38 +hg branch 41.39 +hg branch bar 41.40 +echo new file > newfile 41.41 +hg commit -A -m 'Third commit' 41.42 +hg tip 41.43 + 41.44 +#$ name: parents 41.45 + 41.46 +hg parents 41.47 +hg branches 41.48 + 41.49 +#$ name: update-switchy 41.50 + 41.51 +hg update foo 41.52 +hg parents 41.53 +hg update bar 41.54 +hg parents 41.55 + 41.56 +#$ name: update-nothing 41.57 + 41.58 +hg update foo 41.59 +hg update 41.60 + 41.61 +#$ name: foo-commit 41.62 + 41.63 +echo something > somefile 41.64 +hg commit -A -m 'New file' 41.65 +hg heads 41.66 + 41.67 +#$ name: update-bar 41.68 + 41.69 +hg update bar 41.70 + 41.71 +#$ name: merge 41.72 + 41.73 +hg branch 41.74 +hg merge foo 41.75 +hg commit -m 'Merge' 41.76 +hg tip
42.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 42.2 +++ b/es/examples/branch-repo Thu Jan 29 22:00:07 2009 -0800 42.3 @@ -0,0 +1,48 @@ 42.4 +#!/bin/bash 42.5 + 42.6 +hg init myproject 42.7 +cd myproject 42.8 +echo hello > myfile 42.9 +hg commit -A -m 'Initial commit' 42.10 +cd .. 42.11 + 42.12 +#$ name: tag 42.13 + 42.14 +cd myproject 42.15 +hg tag v1.0 42.16 + 42.17 +#$ name: clone 42.18 + 42.19 +cd .. 42.20 +hg clone myproject myproject-1.0.1 42.21 + 42.22 +#$ name: bugfix 42.23 + 42.24 +hg clone myproject-1.0.1 my-1.0.1-bugfix 42.25 +cd my-1.0.1-bugfix 42.26 +echo 'I fixed a bug using only echo!' >> myfile 42.27 +hg commit -m 'Important fix for 1.0.1' 42.28 +#$ ignore: /tmp/branch-repo.* 42.29 +hg push 42.30 + 42.31 +#$ name: new 42.32 + 42.33 +cd .. 42.34 +hg clone myproject my-feature 42.35 +cd my-feature 42.36 +echo 'This sure is an exciting new feature!' > mynewfile 42.37 +hg commit -A -m 'New feature' 42.38 +hg push 42.39 + 42.40 +#$ name: pull 42.41 + 42.42 +cd .. 42.43 +hg clone myproject myproject-merge 42.44 +cd myproject-merge 42.45 +hg pull ../myproject-1.0.1 42.46 + 42.47 +#$ name: merge 42.48 + 42.49 +hg merge 42.50 +hg commit -m 'Merge bugfix from 1.0.1 branch' 42.51 +hg push
43.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 43.2 +++ b/es/examples/branching Thu Jan 29 22:00:07 2009 -0800 43.3 @@ -0,0 +1,63 @@ 43.4 +#!/bin/bash 43.5 + 43.6 +#$ name: init 43.7 + 43.8 +hg init main 43.9 +cd main 43.10 +echo 'This is a boring feature.' > myfile 43.11 +hg commit -A -m 'We have reached an important milestone!' 43.12 + 43.13 +#$ name: tag 43.14 + 43.15 +hg tag v1.0 43.16 +hg tip 43.17 +hg tags 43.18 + 43.19 +#$ name: main 43.20 + 43.21 +cd ../main 43.22 +echo 'This is exciting and new!' >> myfile 43.23 +hg commit -m 'Add a new feature' 43.24 +cat myfile 43.25 + 43.26 +#$ name: update 43.27 + 43.28 +cd .. 43.29 +hg clone -U main main-old 43.30 +cd main-old 43.31 +hg update v1.0 43.32 +cat myfile 43.33 + 43.34 +#$ name: clone 43.35 + 43.36 +cd .. 43.37 +hg clone -rv1.0 main stable 43.38 + 43.39 +#$ name: stable 43.40 + 43.41 +hg clone stable stable-fix 43.42 +cd stable-fix 43.43 +echo 'This is a fix to a boring feature.' > myfile 43.44 +hg commit -m 'Fix a bug' 43.45 +#$ ignore: /tmp/branching.* 43.46 +hg push 43.47 + 43.48 +#$ name: 43.49 + 43.50 +export HGMERGE=$(mktemp) 43.51 +echo '#!/bin/sh' > $HGMERGE 43.52 +echo 'echo "This is a fix to a boring feature." > "$1"' >> $HGMERGE 43.53 +echo 'echo "This is exciting and new!" >> "$1"' >> $HGMERGE 43.54 +chmod 700 $HGMERGE 43.55 + 43.56 +#$ name: merge 43.57 + 43.58 +cd ../main 43.59 +hg pull ../stable 43.60 +hg merge 43.61 +hg commit -m 'Bring in bugfix from stable branch' 43.62 +cat myfile 43.63 + 43.64 +#$ name: 43.65 + 43.66 +rm $HGMERGE
44.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 44.2 +++ b/es/examples/cmdref Thu Jan 29 22:00:07 2009 -0800 44.3 @@ -0,0 +1,22 @@ 44.4 +#!/bin/bash 44.5 + 44.6 +hg init diff 44.7 +cd diff 44.8 +cat > myfile.c <<EOF 44.9 +int myfunc() 44.10 +{ 44.11 + return 1; 44.12 +} 44.13 +EOF 44.14 +hg ci -Ama 44.15 + 44.16 +sed -ie 's/return 1/return 10/' myfile.c 44.17 + 44.18 +#$ name: diff-p 44.19 + 44.20 +echo '[diff]' >> $HGRC 44.21 +echo 'showfunc = False' >> $HGRC 44.22 + 44.23 +hg diff 44.24 + 44.25 +hg diff -p
45.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 45.2 +++ b/es/examples/daily.copy Thu Jan 29 22:00:07 2009 -0800 45.3 @@ -0,0 +1,82 @@ 45.4 +#!/bin/bash 45.5 + 45.6 +#$ name: init 45.7 + 45.8 +hg init my-copy 45.9 +cd my-copy 45.10 +echo line > file 45.11 +hg add file 45.12 +hg commit -m 'Added a file' 45.13 + 45.14 +#$ name: clone 45.15 + 45.16 +cd .. 45.17 +hg clone my-copy your-copy 45.18 + 45.19 +#$ name: copy 45.20 + 45.21 +cd my-copy 45.22 +hg copy file new-file 45.23 + 45.24 +#$ name: status 45.25 + 45.26 +hg status 45.27 + 45.28 +#$ name: status-copy 45.29 + 45.30 +hg status -C 45.31 +hg commit -m 'Copied file' 45.32 + 45.33 +#$ name: other 45.34 + 45.35 +cd ../your-copy 45.36 +echo 'new contents' >> file 45.37 +hg commit -m 'Changed file' 45.38 + 45.39 +#$ name: cat 45.40 + 45.41 +cat file 45.42 +cat ../my-copy/new-file 45.43 + 45.44 +#$ name: merge 45.45 + 45.46 +hg pull ../my-copy 45.47 +hg merge 45.48 +cat new-file 45.49 + 45.50 +#$ name: 45.51 + 45.52 +cd .. 45.53 +hg init copy-example 45.54 +cd copy-example 45.55 +echo a > a 45.56 +echo b > b 45.57 +mkdir c 45.58 +mkdir c/a 45.59 +echo c > c/a/c 45.60 +hg ci -Ama 45.61 + 45.62 +#$ name: simple 45.63 + 45.64 +mkdir k 45.65 +hg copy a k 45.66 +ls k 45.67 + 45.68 +#$ name: dir-dest 45.69 + 45.70 +mkdir d 45.71 +hg copy a b d 45.72 +ls d 45.73 + 45.74 +#$ name: dir-src 45.75 + 45.76 +hg copy c e 45.77 + 45.78 +#$ name: dir-src-dest 45.79 + 45.80 +hg copy c d 45.81 + 45.82 +#$ name: after 45.83 + 45.84 +cp a z 45.85 +hg copy --after a z
46.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 46.2 +++ b/es/examples/daily.files Thu Jan 29 22:00:07 2009 -0800 46.3 @@ -0,0 +1,93 @@ 46.4 +#!/bin/bash 46.5 + 46.6 +#$ name: add 46.7 + 46.8 +hg init add-example 46.9 +cd add-example 46.10 +echo a > a 46.11 +hg status 46.12 +hg add a 46.13 +hg status 46.14 +hg commit -m 'Added one file' 46.15 +hg status 46.16 + 46.17 +#$ name: add-dir 46.18 + 46.19 +mkdir b 46.20 +echo b > b/b 46.21 +echo c > b/c 46.22 +mkdir b/d 46.23 +echo d > b/d/d 46.24 +hg add b 46.25 +hg commit -m 'Added all files in subdirectory' 46.26 + 46.27 +#$ name: 46.28 + 46.29 +cd .. 46.30 + 46.31 +#$ name: hidden 46.32 + 46.33 +hg init hidden-example 46.34 +cd hidden-example 46.35 +mkdir empty 46.36 +touch empty/.hidden 46.37 +hg add empty/.hidden 46.38 +hg commit -m 'Manage an empty-looking directory' 46.39 +ls empty 46.40 +cd .. 46.41 +hg clone hidden-example tmp 46.42 +ls tmp 46.43 +ls tmp/empty 46.44 + 46.45 +#$ name: remove 46.46 + 46.47 +hg init remove-example 46.48 +cd remove-example 46.49 +echo a > a 46.50 +mkdir b 46.51 +echo b > b/b 46.52 +hg add a b 46.53 +hg commit -m 'Small example for file removal' 46.54 +hg remove a 46.55 +hg status 46.56 +hg remove b 46.57 + 46.58 +#$ name: 46.59 + 46.60 +cd .. 46.61 + 46.62 +#$ name: missing 46.63 +hg init missing-example 46.64 +cd missing-example 46.65 +echo a > a 46.66 +hg add a 46.67 +hg commit -m 'File about to be missing' 46.68 +rm a 46.69 +hg status 46.70 + 46.71 +#$ name: remove-after 46.72 + 46.73 +hg remove --after a 46.74 +hg status 46.75 + 46.76 +#$ name: recover-missing 46.77 +hg revert a 46.78 +cat a 46.79 +hg status 46.80 + 46.81 +#$ name: 46.82 + 46.83 +cd .. 46.84 + 46.85 +#$ name: addremove 46.86 + 46.87 +hg init addremove-example 46.88 +cd addremove-example 46.89 +echo a > a 46.90 +echo b > b 46.91 +hg addremove 46.92 + 46.93 +#$ name: commit-addremove 46.94 + 46.95 +echo c > c 46.96 +hg commit -A -m 'Commit with addremove'
47.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 47.2 +++ b/es/examples/daily.rename Thu Jan 29 22:00:07 2009 -0800 47.3 @@ -0,0 +1,18 @@ 47.4 +#!/bin/bash 47.5 + 47.6 +hg init a 47.7 +cd a 47.8 +echo a > a 47.9 +hg ci -Ama 47.10 + 47.11 +#$ name: rename 47.12 + 47.13 +hg rename a b 47.14 + 47.15 +#$ name: status 47.16 + 47.17 +hg status 47.18 + 47.19 +#$ name: status-copy 47.20 + 47.21 +hg status -C
48.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 48.2 +++ b/es/examples/daily.revert Thu Jan 29 22:00:07 2009 -0800 48.3 @@ -0,0 +1,74 @@ 48.4 +#!/bin/bash 48.5 + 48.6 +hg init a 48.7 +cd a 48.8 +echo 'original content' > file 48.9 +hg ci -Ama 48.10 + 48.11 +#$ name: modify 48.12 + 48.13 +cat file 48.14 +echo unwanted change >> file 48.15 +hg diff file 48.16 + 48.17 +#$ name: unmodify 48.18 + 48.19 +hg status 48.20 +hg revert file 48.21 +cat file 48.22 + 48.23 +#$ name: status 48.24 + 48.25 +hg status 48.26 +cat file.orig 48.27 + 48.28 +#$ name: 48.29 + 48.30 +rm file.orig 48.31 + 48.32 +#$ name: add 48.33 + 48.34 +echo oops > oops 48.35 +hg add oops 48.36 +hg status oops 48.37 +hg revert oops 48.38 +hg status 48.39 + 48.40 +#$ name: 48.41 + 48.42 +rm oops 48.43 + 48.44 +#$ name: remove 48.45 + 48.46 +hg remove file 48.47 +hg status 48.48 +hg revert file 48.49 +hg status 48.50 +ls file 48.51 + 48.52 +#$ name: missing 48.53 + 48.54 +rm file 48.55 +hg status 48.56 +hg revert file 48.57 +ls file 48.58 + 48.59 +#$ name: copy 48.60 + 48.61 +hg copy file new-file 48.62 +hg revert new-file 48.63 +hg status 48.64 + 48.65 +#$ name: 48.66 + 48.67 +rm new-file 48.68 + 48.69 +#$ name: rename 48.70 + 48.71 +hg rename file new-file 48.72 +hg revert new-file 48.73 +hg status 48.74 + 48.75 +#$ name: rename-orig 48.76 +hg revert file 48.77 +hg status
49.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 49.2 +++ b/es/examples/data/check_whitespace.py Thu Jan 29 22:00:07 2009 -0800 49.3 @@ -0,0 +1,44 @@ 49.4 +#!/usr/bin/python 49.5 + 49.6 +import re 49.7 + 49.8 +def trailing_whitespace(difflines): 49.9 + added, linenum, header = [], 0, False 49.10 + 49.11 + for line in difflines: 49.12 + if header: 49.13 + # remember the name of the file that this diff affects 49.14 + m = re.match(r'(?:---|\+\+\+) ([^\t]+)', line) 49.15 + if m and m.group(1) != '/dev/null': 49.16 + filename = m.group(1).split('/', 1)[-1] 49.17 + if line.startswith('+++ '): 49.18 + header = False 49.19 + continue 49.20 + if line.startswith('diff '): 49.21 + header = True 49.22 + continue 49.23 + # hunk header - save the line number 49.24 + m = re.match(r'@@ -\d+,\d+ \+(\d+),', line) 49.25 + if m: 49.26 + linenum = int(m.group(1)) 49.27 + continue 49.28 + # hunk body - check for an added line with trailing whitespace 49.29 + m = re.match(r'\+.*\s$', line) 49.30 + if m: 49.31 + added.append((filename, linenum)) 49.32 + if line and line[0] in ' +': 49.33 + linenum += 1 49.34 + return added 49.35 + 49.36 +if __name__ == '__main__': 49.37 + import os, sys 49.38 + 49.39 + added = trailing_whitespace(os.popen('hg export tip')) 49.40 + if added: 49.41 + for filename, linenum in added: 49.42 + print >> sys.stderr, ('%s, line %d: trailing whitespace added' % 49.43 + (filename, linenum)) 49.44 + # save the commit message so we don't need to retype it 49.45 + os.system('hg tip --template "{desc}" > .hg/commit.save') 49.46 + print >> sys.stderr, 'commit message saved to .hg/commit.save' 49.47 + sys.exit(1)
50.1 Binary file es/examples/data/netplug-1.2.5.tar.bz2 has changed
51.1 Binary file es/examples/data/netplug-1.2.8.tar.bz2 has changed
52.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 52.2 +++ b/es/examples/data/remove-redundant-null-checks.patch Thu Jan 29 22:00:07 2009 -0800 52.3 @@ -0,0 +1,190 @@ 52.4 + 52.5 +From: Jesper Juhl <jesper.juhl@gmail.com> 52.6 + 52.7 +Remove redundant NULL chck before kfree + tiny CodingStyle cleanup for 52.8 +drivers/ 52.9 + 52.10 +Signed-off-by: Jesper Juhl <jesper.juhl@gmail.com> 52.11 +Signed-off-by: Andrew Morton <akpm@osdl.org> 52.12 +--- 52.13 + 52.14 + drivers/char/agp/sgi-agp.c | 5 ++--- 52.15 + drivers/char/hvcs.c | 11 +++++------ 52.16 + drivers/message/fusion/mptfc.c | 6 ++---- 52.17 + drivers/message/fusion/mptsas.c | 3 +-- 52.18 + drivers/net/fs_enet/fs_enet-mii.c | 3 +-- 52.19 + drivers/net/wireless/ipw2200.c | 22 ++++++---------------- 52.20 + drivers/scsi/libata-scsi.c | 4 +--- 52.21 + drivers/video/au1100fb.c | 3 +-- 52.22 + 8 files changed, 19 insertions(+), 38 deletions(-) 52.23 + 52.24 +diff -puN drivers/char/agp/sgi-agp.c~remove-redundant-null-checks-before-free-in-drivers drivers/char/agp/sgi-agp.c 52.25 +--- a/drivers/char/agp/sgi-agp.c~remove-redundant-null-checks-before-free-in-drivers 52.26 ++++ a/drivers/char/agp/sgi-agp.c 52.27 +@@ -329,9 +329,8 @@ static int __devinit agp_sgi_init(void) 52.28 + 52.29 + static void __devexit agp_sgi_cleanup(void) 52.30 + { 52.31 +- if (sgi_tioca_agp_bridges) 52.32 +- kfree(sgi_tioca_agp_bridges); 52.33 +- sgi_tioca_agp_bridges=NULL; 52.34 ++ kfree(sgi_tioca_agp_bridges); 52.35 ++ sgi_tioca_agp_bridges = NULL; 52.36 + } 52.37 + 52.38 + module_init(agp_sgi_init); 52.39 +diff -puN drivers/char/hvcs.c~remove-redundant-null-checks-before-free-in-drivers drivers/char/hvcs.c 52.40 +--- a/drivers/char/hvcs.c~remove-redundant-null-checks-before-free-in-drivers 52.41 ++++ a/drivers/char/hvcs.c 52.42 +@@ -1320,11 +1320,12 @@ static struct tty_operations hvcs_ops = 52.43 + static int hvcs_alloc_index_list(int n) 52.44 + { 52.45 + int i; 52.46 ++ 52.47 + hvcs_index_list = kmalloc(n * sizeof(hvcs_index_count),GFP_KERNEL); 52.48 + if (!hvcs_index_list) 52.49 + return -ENOMEM; 52.50 + hvcs_index_count = n; 52.51 +- for(i = 0; i < hvcs_index_count; i++) 52.52 ++ for (i = 0; i < hvcs_index_count; i++) 52.53 + hvcs_index_list[i] = -1; 52.54 + return 0; 52.55 + } 52.56 +@@ -1332,11 +1333,9 @@ static int hvcs_alloc_index_list(int n) 52.57 + static void hvcs_free_index_list(void) 52.58 + { 52.59 + /* Paranoia check to be thorough. */ 52.60 +- if (hvcs_index_list) { 52.61 +- kfree(hvcs_index_list); 52.62 +- hvcs_index_list = NULL; 52.63 +- hvcs_index_count = 0; 52.64 +- } 52.65 ++ kfree(hvcs_index_list); 52.66 ++ hvcs_index_list = NULL; 52.67 ++ hvcs_index_count = 0; 52.68 + } 52.69 + 52.70 + static int __init hvcs_module_init(void) 52.71 +diff -puN drivers/message/fusion/mptfc.c~remove-redundant-null-checks-before-free-in-drivers drivers/message/fusion/mptfc.c 52.72 +--- a/drivers/message/fusion/mptfc.c~remove-redundant-null-checks-before-free-in-drivers 52.73 ++++ a/drivers/message/fusion/mptfc.c 52.74 +@@ -305,10 +305,8 @@ mptfc_GetFcDevPage0(MPT_ADAPTER *ioc, in 52.75 + } 52.76 + 52.77 + out: 52.78 +- if (pp0_array) 52.79 +- kfree(pp0_array); 52.80 +- if (p0_array) 52.81 +- kfree(p0_array); 52.82 ++ kfree(pp0_array); 52.83 ++ kfree(p0_array); 52.84 + return rc; 52.85 + } 52.86 + 52.87 +diff -puN drivers/message/fusion/mptsas.c~remove-redundant-null-checks-before-free-in-drivers drivers/message/fusion/mptsas.c 52.88 +--- a/drivers/message/fusion/mptsas.c~remove-redundant-null-checks-before-free-in-drivers 52.89 ++++ a/drivers/message/fusion/mptsas.c 52.90 +@@ -1378,8 +1378,7 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc) 52.91 + return 0; 52.92 + 52.93 + out_free_port_info: 52.94 +- if (hba) 52.95 +- kfree(hba); 52.96 ++ kfree(hba); 52.97 + out: 52.98 + return error; 52.99 + } 52.100 +diff -puN drivers/net/fs_enet/fs_enet-mii.c~remove-redundant-null-checks-before-free-in-drivers drivers/net/fs_enet/fs_enet-mii.c 52.101 +--- a/drivers/net/fs_enet/fs_enet-mii.c~remove-redundant-null-checks-before-free-in-drivers 52.102 ++++ a/drivers/net/fs_enet/fs_enet-mii.c 52.103 +@@ -431,8 +431,7 @@ static struct fs_enet_mii_bus *create_bu 52.104 + return bus; 52.105 + 52.106 + err: 52.107 +- if (bus) 52.108 +- kfree(bus); 52.109 ++ kfree(bus); 52.110 + return ERR_PTR(ret); 52.111 + } 52.112 + 52.113 +diff -puN drivers/net/wireless/ipw2200.c~remove-redundant-null-checks-before-free-in-drivers drivers/net/wireless/ipw2200.c 52.114 +--- a/drivers/net/wireless/ipw2200.c~remove-redundant-null-checks-before-free-in-drivers 52.115 ++++ a/drivers/net/wireless/ipw2200.c 52.116 +@@ -1229,12 +1229,6 @@ static struct ipw_fw_error *ipw_alloc_er 52.117 + return error; 52.118 + } 52.119 + 52.120 +-static void ipw_free_error_log(struct ipw_fw_error *error) 52.121 +-{ 52.122 +- if (error) 52.123 +- kfree(error); 52.124 +-} 52.125 +- 52.126 + static ssize_t show_event_log(struct device *d, 52.127 + struct device_attribute *attr, char *buf) 52.128 + { 52.129 +@@ -1296,10 +1290,9 @@ static ssize_t clear_error(struct device 52.130 + const char *buf, size_t count) 52.131 + { 52.132 + struct ipw_priv *priv = dev_get_drvdata(d); 52.133 +- if (priv->error) { 52.134 +- ipw_free_error_log(priv->error); 52.135 +- priv->error = NULL; 52.136 +- } 52.137 ++ 52.138 ++ kfree(priv->error); 52.139 ++ priv->error = NULL; 52.140 + return count; 52.141 + } 52.142 + 52.143 +@@ -1970,8 +1963,7 @@ static void ipw_irq_tasklet(struct ipw_p 52.144 + struct ipw_fw_error *error = 52.145 + ipw_alloc_error_log(priv); 52.146 + ipw_dump_error_log(priv, error); 52.147 +- if (error) 52.148 +- ipw_free_error_log(error); 52.149 ++ kfree(error); 52.150 + } 52.151 + #endif 52.152 + } else { 52.153 +@@ -11693,10 +11685,8 @@ static void ipw_pci_remove(struct pci_de 52.154 + } 52.155 + } 52.156 + 52.157 +- if (priv->error) { 52.158 +- ipw_free_error_log(priv->error); 52.159 +- priv->error = NULL; 52.160 +- } 52.161 ++ kfree(priv->error); 52.162 ++ priv->error = NULL; 52.163 + 52.164 + #ifdef CONFIG_IPW2200_PROMISCUOUS 52.165 + ipw_prom_free(priv); 52.166 +diff -puN drivers/scsi/libata-scsi.c~remove-redundant-null-checks-before-free-in-drivers drivers/scsi/libata-scsi.c 52.167 +--- a/drivers/scsi/libata-scsi.c~remove-redundant-null-checks-before-free-in-drivers 52.168 ++++ a/drivers/scsi/libata-scsi.c 52.169 +@@ -222,9 +222,7 @@ int ata_cmd_ioctl(struct scsi_device *sc 52.170 + && copy_to_user(arg + sizeof(args), argbuf, argsize)) 52.171 + rc = -EFAULT; 52.172 + error: 52.173 +- if (argbuf) 52.174 +- kfree(argbuf); 52.175 +- 52.176 ++ kfree(argbuf); 52.177 + return rc; 52.178 + } 52.179 + 52.180 +diff -puN drivers/video/au1100fb.c~remove-redundant-null-checks-before-free-in-drivers drivers/video/au1100fb.c 52.181 +--- a/drivers/video/au1100fb.c~remove-redundant-null-checks-before-free-in-drivers 52.182 ++++ a/drivers/video/au1100fb.c 52.183 +@@ -743,8 +743,7 @@ void __exit au1100fb_cleanup(void) 52.184 + { 52.185 + driver_unregister(&au1100fb_driver); 52.186 + 52.187 +- if (drv_info.opt_mode) 52.188 +- kfree(drv_info.opt_mode); 52.189 ++ kfree(drv_info.opt_mode); 52.190 + } 52.191 + 52.192 + module_init(au1100fb_init); 52.193 +_
53.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 53.2 +++ b/es/examples/extdiff Thu Jan 29 22:00:07 2009 -0800 53.3 @@ -0,0 +1,28 @@ 53.4 +#!/bin/bash 53.5 + 53.6 +echo '[extensions]' >> $HGRC 53.7 +echo 'extdiff =' >> $HGRC 53.8 + 53.9 +hg init a 53.10 +cd a 53.11 +echo 'The first line.' > myfile 53.12 +hg ci -Ama 53.13 +echo 'The second line.' >> myfile 53.14 + 53.15 +#$ name: diff 53.16 + 53.17 +hg diff 53.18 + 53.19 +#$ name: extdiff 53.20 + 53.21 +hg extdiff 53.22 + 53.23 +#$ name: extdiff-ctx 53.24 + 53.25 +#$ ignore: ^\*\*\* a.* 53.26 + 53.27 +hg extdiff -o -NprcC5 53.28 + 53.29 +#$ name: 53.30 + 53.31 +exit 0
54.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 54.2 +++ b/es/examples/filenames Thu Jan 29 22:00:07 2009 -0800 54.3 @@ -0,0 +1,61 @@ 54.4 +#!/bin/bash 54.5 + 54.6 +hg init a 54.7 +cd a 54.8 +mkdir -p examples src/watcher 54.9 +touch COPYING MANIFEST.in README setup.py 54.10 +touch examples/performant.py examples/simple.py 54.11 +touch src/main.py src/watcher/_watcher.c src/watcher/watcher.py src/xyzzy.txt 54.12 + 54.13 +#$ name: files 54.14 + 54.15 +hg add COPYING README examples/simple.py 54.16 + 54.17 +#$ name: dirs 54.18 + 54.19 +hg status src 54.20 + 54.21 +#$ name: wdir-subdir 54.22 + 54.23 +cd src 54.24 +hg add -n 54.25 +hg add -n . 54.26 + 54.27 +#$ name: wdir-relname 54.28 + 54.29 +hg status 54.30 +hg status `hg root` 54.31 + 54.32 +#$ name: glob.star 54.33 + 54.34 +hg add 'glob:*.py' 54.35 + 54.36 +#$ name: glob.starstar 54.37 + 54.38 +cd .. 54.39 +hg status 'glob:**.py' 54.40 + 54.41 +#$ name: glob.star-starstar 54.42 + 54.43 +hg status 'glob:*.py' 54.44 +hg status 'glob:**.py' 54.45 + 54.46 +#$ name: glob.question 54.47 + 54.48 +hg status 'glob:**.?' 54.49 + 54.50 +#$ name: glob.range 54.51 + 54.52 +hg status 'glob:**[nr-t]' 54.53 + 54.54 +#$ name: glob.group 54.55 + 54.56 +hg status 'glob:*.{in,py}' 54.57 + 54.58 +#$ name: filter.include 54.59 + 54.60 +hg status -I '*.in' 54.61 + 54.62 +#$ name: filter.exclude 54.63 + 54.64 +hg status -X '**.py' src
55.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 55.2 +++ b/es/examples/hook.msglen Thu Jan 29 22:00:07 2009 -0800 55.3 @@ -0,0 +1,14 @@ 55.4 +#!/bin/sh 55.5 + 55.6 +hg init a 55.7 +cd a 55.8 +echo '[hooks]' > .hg/hgrc 55.9 +echo 'pretxncommit.msglen = test `hg tip --template {desc} | wc -c` -ge 10' >> .hg/hgrc 55.10 + 55.11 +#$ name: go 55.12 + 55.13 +cat .hg/hgrc 55.14 +echo a > a 55.15 +hg add a 55.16 +hg commit -A -m 'too short' 55.17 +hg commit -A -m 'long enough'
56.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 56.2 +++ b/es/examples/hook.simple Thu Jan 29 22:00:07 2009 -0800 56.3 @@ -0,0 +1,37 @@ 56.4 +#!/bin/bash 56.5 + 56.6 +#$ name: init 56.7 + 56.8 +hg init hook-test 56.9 +cd hook-test 56.10 +echo '[hooks]' >> .hg/hgrc 56.11 +echo 'commit = echo committed $HG_NODE' >> .hg/hgrc 56.12 +cat .hg/hgrc 56.13 +echo a > a 56.14 +hg add a 56.15 +hg commit -m 'testing commit hook' 56.16 + 56.17 +#$ name: ext 56.18 +#$ ignore: ^date of commit.* 56.19 + 56.20 +echo 'commit.when = echo -n "date of commit: "; date' >> .hg/hgrc 56.21 +echo a >> a 56.22 +hg commit -m 'i have two hooks' 56.23 + 56.24 +#$ name: 56.25 + 56.26 +echo '#!/bin/sh' >> check_bug_id 56.27 +echo '# check that a commit comment mentions a numeric bug id' >> check_bug_id 56.28 +echo 'hg log -r $1 --template {desc} | grep -q "\<bug *[0-9]"' >> check_bug_id 56.29 +chmod +x check_bug_id 56.30 + 56.31 +#$ name: pretxncommit 56.32 + 56.33 +cat check_bug_id 56.34 + 56.35 +echo 'pretxncommit.bug_id_required = ./check_bug_id $HG_NODE' >> .hg/hgrc 56.36 + 56.37 +echo a >> a 56.38 +hg commit -m 'i am not mentioning a bug id' 56.39 + 56.40 +hg commit -m 'i refer you to bug 666'
57.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 57.2 +++ b/es/examples/hook.ws Thu Jan 29 22:00:07 2009 -0800 57.3 @@ -0,0 +1,31 @@ 57.4 +#!/bin/bash 57.5 + 57.6 +hg init a 57.7 +cd a 57.8 +echo '[hooks]' > .hg/hgrc 57.9 +echo "pretxncommit.whitespace = hg export tip | (! egrep -q '^\\+.*[ \\t]$')" >> .hg/hgrc 57.10 + 57.11 +#$ name: simple 57.12 + 57.13 +cat .hg/hgrc 57.14 +echo 'a ' > a 57.15 +hg commit -A -m 'test with trailing whitespace' 57.16 +echo 'a' > a 57.17 +hg commit -A -m 'drop trailing whitespace and try again' 57.18 + 57.19 +#$ name: 57.20 + 57.21 +echo '[hooks]' > .hg/hgrc 57.22 +echo "pretxncommit.whitespace = .hg/check_whitespace.py" >> .hg/hgrc 57.23 +cp $EXAMPLE_DIR/data/check_whitespace.py .hg 57.24 + 57.25 +#$ name: better 57.26 + 57.27 +cat .hg/hgrc 57.28 +echo 'a ' >> a 57.29 +hg commit -A -m 'add new line with trailing whitespace' 57.30 +sed -i 's, *$,,' a 57.31 +hg commit -A -m 'trimmed trailing whitespace' 57.32 + 57.33 +#$ name: 57.34 +exit 0
58.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 58.2 +++ b/es/examples/issue29 Thu Jan 29 22:00:07 2009 -0800 58.3 @@ -0,0 +1,22 @@ 58.4 +#!/bin/bash 58.5 + 58.6 +#$ name: go 58.7 + 58.8 +hg init issue29 58.9 +cd issue29 58.10 +echo a > a 58.11 +hg ci -Ama 58.12 +echo b > b 58.13 +hg ci -Amb 58.14 +hg up 0 58.15 +mkdir b 58.16 +echo b > b/b 58.17 +hg ci -Amc 58.18 + 58.19 +#$ ignore: abort: Is a directory: .* 58.20 +hg merge 58.21 + 58.22 +#$ name: 58.23 +# This error is expected from the failed merge. 58.24 + 58.25 +exit 0
59.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 59.2 +++ b/es/examples/mq.dodiff Thu Jan 29 22:00:07 2009 -0800 59.3 @@ -0,0 +1,14 @@ 59.4 +#!/bin/bash 59.5 + 59.6 +#$ name: diff 59.7 + 59.8 +echo 'this is my original thought' > oldfile 59.9 +echo 'i have changed my mind' > newfile 59.10 + 59.11 +diff -u oldfile newfile > tiny.patch 59.12 + 59.13 +cat tiny.patch 59.14 + 59.15 +patch < tiny.patch 59.16 + 59.17 +cat oldfile
60.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 60.2 +++ b/es/examples/mq.guards Thu Jan 29 22:00:07 2009 -0800 60.3 @@ -0,0 +1,67 @@ 60.4 +#!/bin/bash 60.5 + 60.6 +echo '[extensions]' >> $HGRC 60.7 +echo 'hgext.mq =' >> $HGRC 60.8 + 60.9 +hg init a 60.10 +cd a 60.11 + 60.12 +#$ name: init 60.13 + 60.14 +hg qinit 60.15 +hg qnew hello.patch 60.16 +echo hello > hello 60.17 +hg add hello 60.18 +hg qrefresh 60.19 +hg qnew goodbye.patch 60.20 +echo goodbye > goodbye 60.21 +hg add goodbye 60.22 +hg qrefresh 60.23 + 60.24 +#$ name: qguard 60.25 + 60.26 +hg qguard 60.27 + 60.28 +#$ name: qguard.pos 60.29 + 60.30 +hg qguard +foo 60.31 +hg qguard 60.32 + 60.33 +#$ name: qguard.neg 60.34 + 60.35 +hg qguard hello.patch -quux 60.36 +hg qguard hello.patch 60.37 + 60.38 +#$ name: series 60.39 + 60.40 +cat .hg/patches/series 60.41 + 60.42 +#$ name: qselect.foo 60.43 + 60.44 +hg qpop -a 60.45 +hg qselect 60.46 +hg qselect foo 60.47 +hg qselect 60.48 + 60.49 +#$ name: qselect.cat 60.50 + 60.51 +cat .hg/patches/guards 60.52 + 60.53 +#$ name: qselect.qpush 60.54 +hg qpush -a 60.55 + 60.56 +#$ name: qselect.error 60.57 + 60.58 +hg qselect +foo 60.59 + 60.60 +#$ name: qselect.quux 60.61 + 60.62 +hg qselect quux 60.63 +hg qpop -a 60.64 +hg qpush -a 60.65 + 60.66 +#$ name: qselect.foobar 60.67 + 60.68 +hg qselect foo bar 60.69 +hg qpop -a 60.70 +hg qpush -a
61.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 61.2 +++ b/es/examples/mq.id Thu Jan 29 22:00:07 2009 -0800 61.3 @@ -0,0 +1,28 @@ 61.4 +#!/bin/sh 61.5 + 61.6 +echo '[extensions]' >> $HGRC 61.7 +echo 'hgext.mq =' >> $HGRC 61.8 + 61.9 +hg init a 61.10 +cd a 61.11 +hg qinit 61.12 +echo 'int x;' > test.c 61.13 +hg ci -Ama 61.14 + 61.15 +hg qnew first.patch 61.16 +echo 'float c;' >> test.c 61.17 +hg qrefresh 61.18 + 61.19 +hg qnew second.patch 61.20 +echo 'double u;' > other.c 61.21 +hg add other.c 61.22 +hg qrefresh 61.23 + 61.24 +#$ name: output 61.25 + 61.26 +hg qapplied 61.27 +hg log -r qbase:qtip 61.28 +hg export second.patch 61.29 + 61.30 +#$ name: 61.31 +exit 0
62.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 62.2 +++ b/es/examples/mq.qinit-help Thu Jan 29 22:00:07 2009 -0800 62.3 @@ -0,0 +1,7 @@ 62.4 +#!/bin/bash 62.5 + 62.6 +echo '[extensions]' >> $HGRC 62.7 +echo 'hgext.mq =' >> $HGRC 62.8 + 62.9 +#$ name: help 62.10 +hg help qinit
63.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 63.2 +++ b/es/examples/mq.tarball Thu Jan 29 22:00:07 2009 -0800 63.3 @@ -0,0 +1,51 @@ 63.4 +#!/bin/bash 63.5 + 63.6 +cp $EXAMPLE_DIR/data/netplug-*.tar.bz2 . 63.7 +ln -s /bin/true download 63.8 +export PATH=`pwd`:$PATH 63.9 + 63.10 +#$ name: download 63.11 + 63.12 +download netplug-1.2.5.tar.bz2 63.13 +tar jxf netplug-1.2.5.tar.bz2 63.14 +cd netplug-1.2.5 63.15 +hg init 63.16 +hg commit -q --addremove --message netplug-1.2.5 63.17 +cd .. 63.18 +hg clone netplug-1.2.5 netplug 63.19 + 63.20 +#$ name: 63.21 + 63.22 +cd netplug 63.23 +echo '[extensions]' >> $HGRC 63.24 +echo 'hgext.mq =' >> $HGRC 63.25 +cd .. 63.26 + 63.27 +#$ name: qinit 63.28 + 63.29 +cd netplug 63.30 +hg qinit 63.31 +hg qnew -m 'fix build problem with gcc 4' build-fix.patch 63.32 +perl -pi -e 's/int addr_len/socklen_t addr_len/' netlink.c 63.33 +hg qrefresh 63.34 +hg tip -p 63.35 + 63.36 +#$ name: newsource 63.37 + 63.38 +hg qpop -a 63.39 +cd .. 63.40 +download netplug-1.2.8.tar.bz2 63.41 +hg clone netplug-1.2.5 netplug-1.2.8 63.42 +cd netplug-1.2.8 63.43 +hg locate -0 | xargs -0 rm 63.44 +cd .. 63.45 +tar jxf netplug-1.2.8.tar.bz2 63.46 +cd netplug-1.2.8 63.47 +hg commit --addremove --message netplug-1.2.8 63.48 + 63.49 +#$ name: repush 63.50 + 63.51 +cd ../netplug 63.52 +hg pull ../netplug-1.2.8 63.53 +hg qpush -a 63.54 +
64.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 64.2 +++ b/es/examples/mq.tools Thu Jan 29 22:00:07 2009 -0800 64.3 @@ -0,0 +1,11 @@ 64.4 +#!/bin/bash 64.5 + 64.6 +cp $EXAMPLE_DIR/data/remove-redundant-null-checks.patch . 64.7 + 64.8 +#$ name: tools 64.9 +diffstat -p1 remove-redundant-null-checks.patch 64.10 + 64.11 +filterdiff -i '*/video/*' remove-redundant-null-checks.patch 64.12 + 64.13 +#$ name: lsdiff 64.14 +lsdiff -nvv remove-redundant-null-checks.patch
65.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 65.2 +++ b/es/examples/mq.tutorial Thu Jan 29 22:00:07 2009 -0800 65.3 @@ -0,0 +1,74 @@ 65.4 +#!/bin/bash 65.5 + 65.6 +echo '[extensions]' >> $HGRC 65.7 +echo 'hgext.mq =' >> $HGRC 65.8 + 65.9 +#$ name: qinit 65.10 + 65.11 +hg init mq-sandbox 65.12 +cd mq-sandbox 65.13 +echo 'line 1' > file1 65.14 +echo 'another line 1' > file2 65.15 +hg add file1 file2 65.16 +hg commit -m'first change' 65.17 + 65.18 +hg qinit 65.19 + 65.20 +#$ name: qnew 65.21 + 65.22 +hg tip 65.23 +hg qnew first.patch 65.24 +hg tip 65.25 +ls .hg/patches 65.26 + 65.27 +#$ name: qrefresh 65.28 +#$ ignore: \s+200[78]-.* 65.29 + 65.30 +echo 'line 2' >> file1 65.31 +hg diff 65.32 +hg qrefresh 65.33 +hg diff 65.34 +hg tip --style=compact --patch 65.35 + 65.36 +#$ name: qrefresh2 65.37 + 65.38 +echo 'line 3' >> file1 65.39 +hg status 65.40 +hg qrefresh 65.41 +hg tip --style=compact --patch 65.42 + 65.43 +#$ name: qnew2 65.44 + 65.45 +hg qnew second.patch 65.46 +hg log --style=compact --limit=2 65.47 +echo 'line 4' >> file1 65.48 +hg qrefresh 65.49 +hg tip --style=compact --patch 65.50 +hg annotate file1 65.51 + 65.52 +#$ name: qseries 65.53 + 65.54 +hg qseries 65.55 +hg qapplied 65.56 + 65.57 +#$ name: qpop 65.58 + 65.59 +hg qapplied 65.60 +hg qpop 65.61 +hg qseries 65.62 +hg qapplied 65.63 +cat file1 65.64 + 65.65 +#$ name: qpush-a 65.66 + 65.67 +hg qpush -a 65.68 +cat file1 65.69 + 65.70 +#$ name: add 65.71 + 65.72 +echo 'file 3, line 1' >> file3 65.73 +hg qnew add-file3.patch 65.74 +hg qnew -f add-file3.patch 65.75 + 65.76 +#$ name: 65.77 +exit 0
66.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 66.2 +++ b/es/examples/rename.divergent Thu Jan 29 22:00:07 2009 -0800 66.3 @@ -0,0 +1,33 @@ 66.4 +#!/bin/bash 66.5 + 66.6 +hg init orig 66.7 +cd orig 66.8 +echo foo > foo 66.9 +hg ci -A -m 'First commit' 66.10 +cd .. 66.11 + 66.12 +#$ name: clone 66.13 + 66.14 +hg clone orig anne 66.15 +hg clone orig bob 66.16 + 66.17 +#$ name: rename.anne 66.18 + 66.19 +cd anne 66.20 +hg mv foo bar 66.21 +hg ci -m 'Rename foo to bar' 66.22 + 66.23 +#$ name: rename.bob 66.24 + 66.25 +cd ../bob 66.26 +hg mv foo quux 66.27 +hg ci -m 'Rename foo to quux' 66.28 + 66.29 +#$ name: merge 66.30 +# See http://www.selenic.com/mercurial/bts/issue455 66.31 + 66.32 +cd ../orig 66.33 +hg pull -u ../anne 66.34 +hg pull ../bob 66.35 +hg merge 66.36 +ls
67.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 67.2 +++ b/es/examples/rollback Thu Jan 29 22:00:07 2009 -0800 67.3 @@ -0,0 +1,37 @@ 67.4 +#!/bin/bash 67.5 + 67.6 +hg init a 67.7 +cd a 67.8 +echo a > a 67.9 +hg ci -A -m 'First commit' 67.10 + 67.11 +echo a >> a 67.12 + 67.13 +#$ name: tip 67.14 + 67.15 +#$ name: commit 67.16 + 67.17 +hg status 67.18 +echo b > b 67.19 +hg commit -m 'Add file b' 67.20 + 67.21 +#$ name: status 67.22 + 67.23 +hg status 67.24 +hg tip 67.25 + 67.26 +#$ name: rollback 67.27 + 67.28 +hg rollback 67.29 +hg tip 67.30 +hg status 67.31 + 67.32 +#$ name: add 67.33 + 67.34 +hg add b 67.35 +hg commit -m 'Add file b, this time for real' 67.36 + 67.37 +#$ name: twice 67.38 + 67.39 +hg rollback 67.40 +hg rollback
68.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 68.2 +++ b/es/examples/run-example Thu Jan 29 22:00:07 2009 -0800 68.3 @@ -0,0 +1,391 @@ 68.4 +#!/usr/bin/env python 68.5 +# 68.6 +# This program takes something that resembles a shell script and runs 68.7 +# it, spitting input (commands from the script) and output into text 68.8 +# files, for use in examples. 68.9 + 68.10 +import cStringIO 68.11 +import errno 68.12 +import getopt 68.13 +import os 68.14 +import pty 68.15 +import re 68.16 +import select 68.17 +import shutil 68.18 +import signal 68.19 +import stat 68.20 +import sys 68.21 +import tempfile 68.22 +import time 68.23 + 68.24 +tex_subs = { 68.25 + '\\': '\\textbackslash{}', 68.26 + '{': '\\{', 68.27 + '}': '\\}', 68.28 + } 68.29 + 68.30 +def gensubs(s): 68.31 + start = 0 68.32 + for i, c in enumerate(s): 68.33 + sub = tex_subs.get(c) 68.34 + if sub: 68.35 + yield s[start:i] 68.36 + start = i + 1 68.37 + yield sub 68.38 + yield s[start:] 68.39 + 68.40 +def tex_escape(s): 68.41 + return ''.join(gensubs(s)) 68.42 + 68.43 +def maybe_unlink(name): 68.44 + try: 68.45 + os.unlink(name) 68.46 + return True 68.47 + except OSError, err: 68.48 + if err.errno != errno.ENOENT: 68.49 + raise 68.50 + return False 68.51 + 68.52 +def find_path_to(program): 68.53 + for p in os.environ.get('PATH', os.defpath).split(os.pathsep): 68.54 + name = os.path.join(p, program) 68.55 + if os.access(name, os.X_OK): 68.56 + return p 68.57 + return None 68.58 + 68.59 +class example: 68.60 + shell = '/usr/bin/env bash' 68.61 + ps1 = '__run_example_ps1__ ' 68.62 + ps2 = '__run_example_ps2__ ' 68.63 + pi_re = re.compile(r'#\$\s*(name|ignore):\s*(.*)$') 68.64 + 68.65 + timeout = 10 68.66 + 68.67 + def __init__(self, name, verbose): 68.68 + self.name = name 68.69 + self.verbose = verbose 68.70 + self.poll = select.poll() 68.71 + 68.72 + def parse(self): 68.73 + '''yield each hunk of input from the file.''' 68.74 + fp = open(self.name) 68.75 + cfp = cStringIO.StringIO() 68.76 + for line in fp: 68.77 + cfp.write(line) 68.78 + if not line.rstrip().endswith('\\'): 68.79 + yield cfp.getvalue() 68.80 + cfp.seek(0) 68.81 + cfp.truncate() 68.82 + 68.83 + def status(self, s): 68.84 + sys.stdout.write(s) 68.85 + if not s.endswith('\n'): 68.86 + sys.stdout.flush() 68.87 + 68.88 + def send(self, s): 68.89 + if self.verbose: 68.90 + print >> sys.stderr, '>', self.debugrepr(s) 68.91 + while s: 68.92 + count = os.write(self.cfd, s) 68.93 + s = s[count:] 68.94 + 68.95 + def debugrepr(self, s): 68.96 + rs = repr(s) 68.97 + limit = 60 68.98 + if len(rs) > limit: 68.99 + return ('%s%s ... [%d bytes]' % (rs[:limit], rs[0], len(s))) 68.100 + else: 68.101 + return rs 68.102 + 68.103 + timeout = 5 68.104 + 68.105 + def read(self, hint): 68.106 + events = self.poll.poll(self.timeout * 1000) 68.107 + if not events: 68.108 + print >> sys.stderr, ('[%stimed out after %d seconds]' % 68.109 + (hint, self.timeout)) 68.110 + os.kill(self.pid, signal.SIGHUP) 68.111 + return '' 68.112 + return os.read(self.cfd, 1024) 68.113 + 68.114 + def receive(self, hint): 68.115 + out = cStringIO.StringIO() 68.116 + while True: 68.117 + try: 68.118 + if self.verbose: 68.119 + sys.stderr.write('< ') 68.120 + s = self.read(hint) 68.121 + except OSError, err: 68.122 + if err.errno == errno.EIO: 68.123 + return '', '' 68.124 + raise 68.125 + if self.verbose: 68.126 + print >> sys.stderr, self.debugrepr(s) 68.127 + out.write(s) 68.128 + s = out.getvalue() 68.129 + if s.endswith(self.ps1): 68.130 + return self.ps1, s.replace('\r\n', '\n')[:-len(self.ps1)] 68.131 + if s.endswith(self.ps2): 68.132 + return self.ps2, s.replace('\r\n', '\n')[:-len(self.ps2)] 68.133 + 68.134 + def sendreceive(self, s, hint): 68.135 + self.send(s) 68.136 + ps, r = self.receive(hint) 68.137 + if r.startswith(s): 68.138 + r = r[len(s):] 68.139 + return ps, r 68.140 + 68.141 + def run(self): 68.142 + ofp = None 68.143 + basename = os.path.basename(self.name) 68.144 + self.status('running %s ' % basename) 68.145 + tmpdir = tempfile.mkdtemp(prefix=basename) 68.146 + 68.147 + # remove the marker file that we tell make to use to see if 68.148 + # this run succeeded 68.149 + maybe_unlink(self.name + '.run') 68.150 + 68.151 + rcfile = os.path.join(tmpdir, '.hgrc') 68.152 + rcfp = open(rcfile, 'w') 68.153 + print >> rcfp, '[ui]' 68.154 + print >> rcfp, "username = Bryan O'Sullivan <bos@serpentine.com>" 68.155 + 68.156 + rcfile = os.path.join(tmpdir, '.bashrc') 68.157 + rcfp = open(rcfile, 'w') 68.158 + print >> rcfp, 'PS1="%s"' % self.ps1 68.159 + print >> rcfp, 'PS2="%s"' % self.ps2 68.160 + print >> rcfp, 'unset HISTFILE' 68.161 + path = ['/usr/bin', '/bin'] 68.162 + hg = find_path_to('hg') 68.163 + if hg and hg not in path: 68.164 + path.append(hg) 68.165 + def re_export(envar): 68.166 + v = os.getenv(envar) 68.167 + if v is not None: 68.168 + print >> rcfp, 'export ' + envar + '=' + v 68.169 + print >> rcfp, 'export PATH=' + ':'.join(path) 68.170 + re_export('PYTHONPATH') 68.171 + print >> rcfp, 'export EXAMPLE_DIR="%s"' % os.getcwd() 68.172 + print >> rcfp, 'export HGMERGE=merge' 68.173 + print >> rcfp, 'export LANG=C' 68.174 + print >> rcfp, 'export LC_ALL=C' 68.175 + print >> rcfp, 'export TZ=GMT' 68.176 + print >> rcfp, 'export HGRC="%s/.hgrc"' % tmpdir 68.177 + print >> rcfp, 'export HGRCPATH=$HGRC' 68.178 + print >> rcfp, 'cd %s' % tmpdir 68.179 + rcfp.close() 68.180 + sys.stdout.flush() 68.181 + sys.stderr.flush() 68.182 + self.pid, self.cfd = pty.fork() 68.183 + if self.pid == 0: 68.184 + cmdline = ['/usr/bin/env', '-i', 'bash', '--noediting', 68.185 + '--noprofile', '--norc'] 68.186 + try: 68.187 + os.execv(cmdline[0], cmdline) 68.188 + except OSError, err: 68.189 + print >> sys.stderr, '%s: %s' % (cmdline[0], err.strerror) 68.190 + sys.stderr.flush() 68.191 + os._exit(0) 68.192 + self.poll.register(self.cfd, select.POLLIN | select.POLLERR | 68.193 + select.POLLHUP) 68.194 + 68.195 + prompts = { 68.196 + '': '', 68.197 + self.ps1: '$', 68.198 + self.ps2: '>', 68.199 + } 68.200 + 68.201 + ignore = [ 68.202 + r'\d+:[0-9a-f]{12}', # changeset number:hash 68.203 + r'[0-9a-f]{40}', # long changeset hash 68.204 + r'[0-9a-f]{12}', # short changeset hash 68.205 + r'^(?:---|\+\+\+) .*', # diff header with dates 68.206 + r'^date:.*', # date 68.207 + #r'^diff -r.*', # "diff -r" is followed by hash 68.208 + r'^# Date \d+ \d+', # hg patch header 68.209 + ] 68.210 + 68.211 + err = False 68.212 + read_hint = '' 68.213 + 68.214 + try: 68.215 + try: 68.216 + # eat first prompt string from shell 68.217 + self.read(read_hint) 68.218 + # setup env and prompt 68.219 + ps, output = self.sendreceive('source %s\n' % rcfile, 68.220 + read_hint) 68.221 + for hunk in self.parse(): 68.222 + # is this line a processing instruction? 68.223 + m = self.pi_re.match(hunk) 68.224 + if m: 68.225 + pi, rest = m.groups() 68.226 + if pi == 'name': 68.227 + self.status('.') 68.228 + out = rest 68.229 + if out in ('err', 'lxo', 'out', 'run', 'tmp'): 68.230 + print >> sys.stderr, ('%s: illegal section ' 68.231 + 'name %r' % 68.232 + (self.name, out)) 68.233 + return 1 68.234 + assert os.sep not in out 68.235 + if ofp is not None: 68.236 + ofp.close() 68.237 + err |= self.rename_output(ofp_basename, ignore) 68.238 + if out: 68.239 + ofp_basename = '%s.%s' % (self.name, out) 68.240 + read_hint = ofp_basename + ' ' 68.241 + ofp = open(ofp_basename + '.tmp', 'w') 68.242 + else: 68.243 + ofp = None 68.244 + elif pi == 'ignore': 68.245 + ignore.append(rest) 68.246 + elif hunk.strip(): 68.247 + # it's something we should execute 68.248 + newps, output = self.sendreceive(hunk, read_hint) 68.249 + if not ofp: 68.250 + continue 68.251 + # first, print the command we ran 68.252 + if not hunk.startswith('#'): 68.253 + nl = hunk.endswith('\n') 68.254 + hunk = ('%s \\textbf{%s}' % 68.255 + (prompts[ps], 68.256 + tex_escape(hunk.rstrip('\n')))) 68.257 + if nl: hunk += '\n' 68.258 + ofp.write(hunk) 68.259 + # then its output 68.260 + ofp.write(tex_escape(output)) 68.261 + ps = newps 68.262 + self.status('\n') 68.263 + except: 68.264 + print >> sys.stderr, '(killed)' 68.265 + os.kill(self.pid, signal.SIGKILL) 68.266 + pid, rc = os.wait() 68.267 + raise 68.268 + else: 68.269 + try: 68.270 + ps, output = self.sendreceive('exit\n', read_hint) 68.271 + if ofp is not None: 68.272 + ofp.write(output) 68.273 + ofp.close() 68.274 + err |= self.rename_output(ofp_basename, ignore) 68.275 + os.close(self.cfd) 68.276 + except IOError: 68.277 + pass 68.278 + os.kill(self.pid, signal.SIGTERM) 68.279 + pid, rc = os.wait() 68.280 + err = err or rc 68.281 + if err: 68.282 + if os.WIFEXITED(rc): 68.283 + print >> sys.stderr, '(exit %s)' % os.WEXITSTATUS(rc) 68.284 + elif os.WIFSIGNALED(rc): 68.285 + print >> sys.stderr, '(signal %s)' % os.WTERMSIG(rc) 68.286 + else: 68.287 + open(self.name + '.run', 'w') 68.288 + return err 68.289 + finally: 68.290 + shutil.rmtree(tmpdir) 68.291 + 68.292 + def rename_output(self, base, ignore): 68.293 + mangle_re = re.compile('(?:' + '|'.join(ignore) + ')') 68.294 + def mangle(s): 68.295 + return mangle_re.sub('', s) 68.296 + def matchfp(fp1, fp2): 68.297 + while True: 68.298 + s1 = mangle(fp1.readline()) 68.299 + s2 = mangle(fp2.readline()) 68.300 + if cmp(s1, s2): 68.301 + break 68.302 + if not s1: 68.303 + return True 68.304 + return False 68.305 + 68.306 + oldname = base + '.out' 68.307 + tmpname = base + '.tmp' 68.308 + errname = base + '.err' 68.309 + errfp = open(errname, 'w+') 68.310 + for line in open(tmpname): 68.311 + errfp.write(mangle_re.sub('', line)) 68.312 + os.rename(tmpname, base + '.lxo') 68.313 + errfp.seek(0) 68.314 + try: 68.315 + oldfp = open(oldname) 68.316 + except IOError, err: 68.317 + if err.errno != errno.ENOENT: 68.318 + raise 68.319 + os.rename(errname, oldname) 68.320 + return False 68.321 + if matchfp(oldfp, errfp): 68.322 + os.unlink(errname) 68.323 + return False 68.324 + else: 68.325 + print >> sys.stderr, '\nOutput of %s has changed!' % base 68.326 + os.system('diff -u %s %s 1>&2' % (oldname, errname)) 68.327 + return True 68.328 + 68.329 +def print_help(exit, msg=None): 68.330 + if msg: 68.331 + print >> sys.stderr, 'Error:', msg 68.332 + print >> sys.stderr, 'Usage: run-example [options] [test...]' 68.333 + print >> sys.stderr, 'Options:' 68.334 + print >> sys.stderr, ' -a --all run all tests in this directory' 68.335 + print >> sys.stderr, ' -h --help print this help message' 68.336 + print >> sys.stderr, ' -v --verbose display extra debug output' 68.337 + sys.exit(exit) 68.338 + 68.339 +def main(path='.'): 68.340 + opts, args = getopt.getopt(sys.argv[1:], '?ahv', 68.341 + ['all', 'help', 'verbose']) 68.342 + verbose = False 68.343 + run_all = False 68.344 + for o, a in opts: 68.345 + if o in ('-h', '-?', '--help'): 68.346 + print_help(0) 68.347 + if o in ('-a', '--all'): 68.348 + run_all = True 68.349 + if o in ('-v', '--verbose'): 68.350 + verbose = True 68.351 + errs = 0 68.352 + if args: 68.353 + for a in args: 68.354 + try: 68.355 + st = os.lstat(a) 68.356 + except OSError, err: 68.357 + print >> sys.stderr, '%s: %s' % (a, err.strerror) 68.358 + errs += 1 68.359 + continue 68.360 + if stat.S_ISREG(st.st_mode) and st.st_mode & 0111: 68.361 + if example(a, verbose).run(): 68.362 + errs += 1 68.363 + else: 68.364 + print >> sys.stderr, '%s: not a file, or not executable' % a 68.365 + errs += 1 68.366 + elif run_all: 68.367 + names = os.listdir(path) 68.368 + names.sort() 68.369 + for name in names: 68.370 + if name == 'run-example' or name.startswith('.'): continue 68.371 + if name.endswith('.out') or name.endswith('~'): continue 68.372 + if name.endswith('.run'): continue 68.373 + pathname = os.path.join(path, name) 68.374 + try: 68.375 + st = os.lstat(pathname) 68.376 + except OSError, err: 68.377 + # could be an output file that was removed while we ran 68.378 + if err.errno != errno.ENOENT: 68.379 + raise 68.380 + continue 68.381 + if stat.S_ISREG(st.st_mode) and st.st_mode & 0111: 68.382 + if example(pathname, verbose).run(): 68.383 + errs += 1 68.384 + print >> open(os.path.join(path, '.run'), 'w'), time.asctime() 68.385 + else: 68.386 + print_help(1, msg='no test names given, and --all not provided') 68.387 + return errs 68.388 + 68.389 +if __name__ == '__main__': 68.390 + try: 68.391 + sys.exit(main()) 68.392 + except KeyboardInterrupt: 68.393 + print >> sys.stderr, 'interrupted!' 68.394 + sys.exit(1)
69.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 69.2 +++ b/es/examples/svn-long.txt Thu Jan 29 22:00:07 2009 -0800 69.3 @@ -0,0 +1,11 @@ 69.4 +------------------------------------------------------------------------ 69.5 +r9653 | sean.hefty | 2006-09-27 14:39:55 -0700 (Wed, 27 Sep 2006) | 5 lines 69.6 +Changed paths: 69.7 + M /gen2/trunk/src/linux-kernel/infiniband/core/cma.c 69.8 + 69.9 +On reporting a route error, also include the status for the error, 69.10 +rather than indicating a status of 0 when an error has occurred. 69.11 + 69.12 +Signed-off-by: Sean Hefty <sean.hefty@intel.com> 69.13 + 69.14 +------------------------------------------------------------------------
70.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 70.2 +++ b/es/examples/svn-short.txt Thu Jan 29 22:00:07 2009 -0800 70.3 @@ -0,0 +1,9 @@ 70.4 +------------------------------------------------------------------------ 70.5 +r9653 | sean.hefty | 2006-09-27 14:39:55 -0700 (Wed, 27 Sep 2006) | 5 lines 70.6 + 70.7 +On reporting a route error, also include the status for the error, 70.8 +rather than indicating a status of 0 when an error has occurred. 70.9 + 70.10 +Signed-off-by: Sean Hefty <sean.hefty@intel.com> 70.11 + 70.12 +------------------------------------------------------------------------
71.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 71.2 +++ b/es/examples/svn.style Thu Jan 29 22:00:07 2009 -0800 71.3 @@ -0,0 +1,2 @@ 71.4 +header = '------------------------------------------------------------------------\n\n' 71.5 +changeset = svn.template
72.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 72.2 +++ b/es/examples/svn.template Thu Jan 29 22:00:07 2009 -0800 72.3 @@ -0,0 +1,5 @@ 72.4 +r{rev} | {author|user} | {date|isodate} ({date|rfc822date}) 72.5 + 72.6 +{desc|strip|fill76} 72.7 + 72.8 +------------------------------------------------------------------------
73.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 73.2 +++ b/es/examples/tag Thu Jan 29 22:00:07 2009 -0800 73.3 @@ -0,0 +1,44 @@ 73.4 +#!/bin/bash 73.5 + 73.6 +#$ name: init 73.7 + 73.8 +hg init mytag 73.9 +cd mytag 73.10 + 73.11 +echo hello > myfile 73.12 +hg commit -A -m 'Initial commit' 73.13 + 73.14 +#$ name: tag 73.15 + 73.16 +hg tag v1.0 73.17 + 73.18 +#$ name: tags 73.19 + 73.20 +hg tags 73.21 + 73.22 +#$ name: log 73.23 + 73.24 +hg log 73.25 + 73.26 +#$ name: log.v1.0 73.27 + 73.28 +echo goodbye > myfile2 73.29 +hg commit -A -m 'Second commit' 73.30 +hg log -r v1.0 73.31 + 73.32 +#$ name: remove 73.33 + 73.34 +hg tag --remove v1.0 73.35 +hg tags 73.36 + 73.37 +#$ name: replace 73.38 + 73.39 +hg tag -r 1 v1.1 73.40 +hg tags 73.41 +hg tag -r 2 v1.1 73.42 +hg tag -f -r 2 v1.1 73.43 +hg tags 73.44 + 73.45 +#$ name: tip 73.46 + 73.47 +hg tip
74.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 74.2 +++ b/es/examples/template.simple Thu Jan 29 22:00:07 2009 -0800 74.3 @@ -0,0 +1,96 @@ 74.4 +#!/bin/bash 74.5 + 74.6 +# So many different bits of random output, it would be a nightmare to 74.7 +# ignore each individually. 74.8 +#$ ignore: .* 74.9 + 74.10 +hg init myrepo 74.11 +cd myrepo 74.12 +echo hello > hello 74.13 +hg commit -Am'added hello' 74.14 + 74.15 +echo hello >> hello 74.16 +echo goodbye > goodbye 74.17 +echo ' added line to end of <<hello>> file.' > ../msg 74.18 +echo '' >> ../msg 74.19 +echo 'in addition, added a file with the helpful name (at least i hope that some might consider it so) of goodbye.' >> ../msg 74.20 + 74.21 +hg commit -Al../msg 74.22 + 74.23 +hg tag mytag 74.24 +hg tag v0.1 74.25 + 74.26 +#$ name: normal 74.27 + 74.28 +hg log -r1 74.29 + 74.30 +#$ name: compact 74.31 + 74.32 +hg log --style compact 74.33 + 74.34 +#$ name: changelog 74.35 + 74.36 +hg log --style changelog 74.37 + 74.38 +#$ name: simplest 74.39 + 74.40 +hg log -r1 --template 'i saw a changeset\n' 74.41 + 74.42 +#$ name: simplesub 74.43 + 74.44 +hg log --template 'i saw a changeset: {desc}\n' 74.45 + 74.46 +#$ name: keywords 74.47 + 74.48 +hg log -r1 --template 'author: {author}\n' 74.49 +hg log -r1 --template 'desc:\n{desc}\n' 74.50 +hg log -r1 --template 'files: {files}\n' 74.51 +hg log -r1 --template 'file_adds: {file_adds}\n' 74.52 +hg log -r1 --template 'file_dels: {file_dels}\n' 74.53 +hg log -r1 --template 'node: {node}\n' 74.54 +hg log -r1 --template 'parents: {parents}\n' 74.55 +hg log -r1 --template 'rev: {rev}\n' 74.56 +hg log -r1 --template 'tags: {tags}\n' 74.57 + 74.58 +#$ name: datekeyword 74.59 + 74.60 +hg log -r1 --template 'date: {date}\n' 74.61 +hg log -r1 --template 'date: {date|isodate}\n' 74.62 + 74.63 +#$ name: manyfilters 74.64 + 74.65 +hg log -r1 --template '{author}\n' 74.66 +hg log -r1 --template '{author|domain}\n' 74.67 +hg log -r1 --template '{author|email}\n' 74.68 +hg log -r1 --template '{author|obfuscate}\n' | cut -c-76 74.69 +hg log -r1 --template '{author|person}\n' 74.70 +hg log -r1 --template '{author|user}\n' 74.71 + 74.72 +hg log -r1 --template 'looks almost right, but actually garbage: {date}\n' 74.73 +hg log -r1 --template '{date|age}\n' 74.74 +hg log -r1 --template '{date|date}\n' 74.75 +hg log -r1 --template '{date|hgdate}\n' 74.76 +hg log -r1 --template '{date|isodate}\n' 74.77 +hg log -r1 --template '{date|rfc822date}\n' 74.78 +hg log -r1 --template '{date|shortdate}\n' 74.79 + 74.80 +hg log -r1 --template '{desc}\n' | cut -c-76 74.81 +hg log -r1 --template '{desc|addbreaks}\n' | cut -c-76 74.82 +hg log -r1 --template '{desc|escape}\n' | cut -c-76 74.83 +hg log -r1 --template '{desc|fill68}\n' 74.84 +hg log -r1 --template '{desc|fill76}\n' 74.85 +hg log -r1 --template '{desc|firstline}\n' 74.86 +hg log -r1 --template '{desc|strip}\n' | cut -c-76 74.87 +hg log -r1 --template '{desc|tabindent}\n' | expand | cut -c-76 74.88 + 74.89 +hg log -r1 --template '{node}\n' 74.90 +hg log -r1 --template '{node|short}\n' 74.91 + 74.92 +#$ name: combine 74.93 + 74.94 +hg log -r1 --template 'description:\n\t{desc|strip|fill68|tabindent}\n' 74.95 + 74.96 +#$ name: rev 74.97 + 74.98 +echo 'changeset = "rev: {rev}\n"' > rev 74.99 +hg log -l1 --style ./rev
75.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 75.2 +++ b/es/examples/template.svnstyle Thu Jan 29 22:00:07 2009 -0800 75.3 @@ -0,0 +1,70 @@ 75.4 +#!/bin/bash 75.5 + 75.6 +svn() { 75.7 + cat $EXAMPLE_DIR/svn-short.txt 75.8 +} 75.9 + 75.10 +#$ name: short 75.11 + 75.12 +svn log -r9653 75.13 + 75.14 +#$ name: 75.15 + 75.16 +hg init myrepo 75.17 +cd myrepo 75.18 + 75.19 +echo hello > hello 75.20 +hg commit -Am'added hello' 75.21 + 75.22 +echo hello >> hello 75.23 +echo goodbye > goodbye 75.24 +echo ' added line to end of <<hello>> file.' > ../msg 75.25 +echo '' >> ../msg 75.26 +echo 'in addition, added a file with the helpful name (at least i hope that some might consider it so) of goodbye.' >> ../msg 75.27 + 75.28 +hg commit -Al../msg 75.29 + 75.30 +hg tag mytag 75.31 +hg tag v0.1 75.32 + 75.33 +echo 'changeset = "{node|short}\n"' > svn.style 75.34 + 75.35 +#$ name: id 75.36 + 75.37 +hg log -r0 --template '{node}' 75.38 + 75.39 +#$ name: simplest 75.40 + 75.41 +cat svn.style 75.42 +hg log -r1 --style svn.style 75.43 + 75.44 +#$ name: 75.45 + 75.46 +echo 'changeset =' > broken.style 75.47 + 75.48 +#$ name: syntax.input 75.49 + 75.50 +cat broken.style 75.51 + 75.52 +#$ name: syntax.error 75.53 + 75.54 +hg log -r1 --style broken.style 75.55 + 75.56 +#$ name: 75.57 + 75.58 +cp $EXAMPLE_DIR/svn.style . 75.59 +cp $EXAMPLE_DIR/svn.template . 75.60 + 75.61 +#$ name: template 75.62 + 75.63 +cat svn.template 75.64 + 75.65 +#$ name: style 75.66 + 75.67 +cat svn.style 75.68 + 75.69 +#$ name: result 75.70 +#$ ignore: \| 200[78].* 75.71 + 75.72 +hg log -r1 --style svn.style 75.73 +
76.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 76.2 +++ b/es/examples/tour Thu Jan 29 22:00:07 2009 -0800 76.3 @@ -0,0 +1,194 @@ 76.4 +#!/bin/bash 76.5 + 76.6 +#$ name: version 76.7 + 76.8 +hg version 76.9 + 76.10 +#$ name: help 76.11 + 76.12 +hg help init 76.13 + 76.14 +#$ name: clone 76.15 + 76.16 +hg clone http://hg.serpentine.com/tutorial/hello 76.17 + 76.18 +#$ name: ls 76.19 +#$ ignore: ^drwx.* 76.20 +#$ ignore: ^total \d+ 76.21 + 76.22 +ls -l 76.23 +ls hello 76.24 + 76.25 +#$ name: ls-a 76.26 + 76.27 +cd hello 76.28 +ls -a 76.29 + 76.30 +#$ name: log 76.31 + 76.32 +hg log 76.33 + 76.34 +#$ name: log-r 76.35 + 76.36 +hg log -r 3 76.37 +hg log -r 0272e0d5a517 76.38 +hg log -r 1 -r 4 76.39 + 76.40 +#$ name: log.range 76.41 + 76.42 +hg log -r 2:4 76.43 + 76.44 +#$ name: log-v 76.45 + 76.46 +hg log -v -r 3 76.47 + 76.48 +#$ name: log-vp 76.49 + 76.50 +hg log -v -p -r 2 76.51 + 76.52 +#$ name: reclone 76.53 + 76.54 +cd .. 76.55 +hg clone hello my-hello 76.56 +cd my-hello 76.57 + 76.58 +#$ name: sed 76.59 + 76.60 +sed -i '/printf/a\\tprintf("hello again!\\n");' hello.c 76.61 + 76.62 +#$ name: status 76.63 + 76.64 +ls 76.65 +hg status 76.66 + 76.67 +#$ name: diff 76.68 + 76.69 +hg diff 76.70 + 76.71 +#$ name: 76.72 + 76.73 +export HGEDITOR='echo Added an extra line of output >' 76.74 + 76.75 +#$ name: commit 76.76 + 76.77 +hg commit 76.78 + 76.79 +#$ name: merge.dummy1 76.80 + 76.81 +hg log -r 5 | grep changeset | cut -c 16-19 2>/dev/null > /tmp/REV5.my-hello 76.82 + 76.83 +#$ name: tip 76.84 + 76.85 +hg tip -vp 76.86 + 76.87 +#$ name: clone-pull 76.88 + 76.89 +cd .. 76.90 +hg clone hello hello-pull 76.91 + 76.92 +#$ name: incoming 76.93 + 76.94 +cd hello-pull 76.95 +hg incoming ../my-hello 76.96 + 76.97 +#$ name: pull 76.98 + 76.99 +hg tip 76.100 +hg pull ../my-hello 76.101 +hg tip 76.102 + 76.103 +#$ name: update 76.104 + 76.105 +grep printf hello.c 76.106 +hg update tip 76.107 +grep printf hello.c 76.108 + 76.109 +#$ name: parents 76.110 + 76.111 +hg parents 76.112 + 76.113 +#$ name: older 76.114 + 76.115 +hg update 2 76.116 +hg parents 76.117 +hg update 76.118 + 76.119 +#$ name: clone-push 76.120 + 76.121 +cd .. 76.122 +hg clone hello hello-push 76.123 + 76.124 +#$ name: outgoing 76.125 + 76.126 +cd my-hello 76.127 +hg outgoing ../hello-push 76.128 + 76.129 +#$ name: push 76.130 + 76.131 +hg push ../hello-push 76.132 + 76.133 +#$ name: push.nothing 76.134 + 76.135 +hg push ../hello-push 76.136 + 76.137 +#$ name: outgoing.net 76.138 + 76.139 +hg outgoing http://hg.serpentine.com/tutorial/hello 76.140 + 76.141 +#$ name: push.net 76.142 + 76.143 +hg push http://hg.serpentine.com/tutorial/hello 76.144 + 76.145 +#$ name: merge.clone 76.146 + 76.147 +cd .. 76.148 +hg clone hello my-new-hello 76.149 +cd my-new-hello 76.150 +sed -i '/printf/i\\tprintf("once more, hello.\\n");' hello.c 76.151 +hg commit -m 'A new hello for a new day.' 76.152 + 76.153 +#$ name: merge.dummy2 76.154 + 76.155 +hg log -r 5 | grep changeset | cut -c 16-19 2>/dev/null > /tmp/REV5.my-new-hello 76.156 + 76.157 +#$ name: merge.cat 76.158 + 76.159 +cat hello.c 76.160 +cat ../my-hello/hello.c 76.161 + 76.162 +#$ name: merge.pull 76.163 + 76.164 +hg pull ../my-hello 76.165 + 76.166 +#$ name: merge.dummy3 76.167 + 76.168 +hg log -r 6 | grep changeset | cut -c 16-19 2>/dev/null > /tmp/REV6.my-new-hello 76.169 + 76.170 +#$ name: merge.heads 76.171 + 76.172 +hg heads 76.173 + 76.174 +#$ name: merge.update 76.175 + 76.176 +hg update 76.177 + 76.178 +#$ name: merge.merge 76.179 + 76.180 +hg merge 76.181 + 76.182 +#$ name: merge.parents 76.183 + 76.184 +hg parents 76.185 +cat hello.c 76.186 + 76.187 +#$ name: merge.commit 76.188 + 76.189 +hg commit -m 'Merged changes' 76.190 + 76.191 +#$ name: merge.dummy4 76.192 + 76.193 +hg log -r 7 | grep changeset | cut -c 16-19 2>/dev/null > /tmp/REV7.my-new-hello 76.194 + 76.195 +#$ name: merge.tip 76.196 + 76.197 +hg tip
77.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 77.2 +++ b/es/examples/tour-merge-conflict Thu Jan 29 22:00:07 2009 -0800 77.3 @@ -0,0 +1,73 @@ 77.4 +#!/bin/bash 77.5 + 77.6 +hg init scam 77.7 +cd scam 77.8 + 77.9 +#$ name: wife 77.10 + 77.11 +cat > letter.txt <<EOF 77.12 +Greetings! 77.13 + 77.14 +I am Mariam Abacha, the wife of former 77.15 +Nigerian dictator Sani Abacha. 77.16 +EOF 77.17 + 77.18 +hg add letter.txt 77.19 +hg commit -m '419 scam, first draft' 77.20 + 77.21 +#$ name: cousin 77.22 + 77.23 +cd .. 77.24 +hg clone scam scam-cousin 77.25 +cd scam-cousin 77.26 + 77.27 +cat > letter.txt <<EOF 77.28 +Greetings! 77.29 + 77.30 +I am Shehu Musa Abacha, cousin to the former 77.31 +Nigerian dictator Sani Abacha. 77.32 +EOF 77.33 + 77.34 +hg commit -m '419 scam, with cousin' 77.35 + 77.36 +#$ name: son 77.37 + 77.38 +cd .. 77.39 +hg clone scam scam-son 77.40 +cd scam-son 77.41 + 77.42 +cat > letter.txt <<EOF 77.43 +Greetings! 77.44 + 77.45 +I am Alhaji Abba Abacha, son of the former 77.46 +Nigerian dictator Sani Abacha. 77.47 +EOF 77.48 + 77.49 +hg commit -m '419 scam, with son' 77.50 + 77.51 +#$ name: pull 77.52 + 77.53 +cd .. 77.54 +hg clone scam-cousin scam-merge 77.55 +cd scam-merge 77.56 +hg pull -u ../scam-son 77.57 + 77.58 +#$ name: merge 77.59 +#$ ignore: [<>]{7} /tmp/.* 77.60 + 77.61 +export HGMERGE=merge 77.62 +hg merge 77.63 +cat letter.txt 77.64 + 77.65 +#$ name: commit 77.66 + 77.67 +cat > letter.txt <<EOF 77.68 +Greetings! 77.69 + 77.70 +I am Bryan O'Sullivan, no relation of the former 77.71 +Nigerian dictator Sani Abacha. 77.72 +EOF 77.73 + 77.74 +hg resolve -m letter.txt 77.75 +hg commit -m 'Send me your money' 77.76 +hg tip
78.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 78.2 +++ b/es/fblinks Thu Jan 29 22:00:07 2009 -0800 78.3 @@ -0,0 +1,1 @@ 78.4 +../en/fblinks 78.5 \ No newline at end of file
79.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 79.2 +++ b/es/feature-branches.dot Thu Jan 29 22:00:07 2009 -0800 79.3 @@ -0,0 +1,8 @@ 79.4 +digraph feature_branches { 79.5 + maestro -> cripto; 79.6 + maestro -> sistemadearchivos; 79.7 + maestro -> ipc; 79.8 + maestro -> memoria; 79.9 + maestro -> red; 79.10 + maestro -> seguridad; 79.11 +}
80.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 80.2 +++ b/es/filelog.svg Thu Jan 29 22:00:07 2009 -0800 80.3 @@ -0,0 +1,381 @@ 80.4 +<?xml version="1.0" encoding="UTF-8" standalone="no"?> 80.5 +<!-- Created with Inkscape (http://www.inkscape.org/) --> 80.6 +<svg 80.7 + xmlns:dc="http://purl.org/dc/elements/1.1/" 80.8 + xmlns:cc="http://creativecommons.org/ns#" 80.9 + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 80.10 + xmlns:svg="http://www.w3.org/2000/svg" 80.11 + xmlns="http://www.w3.org/2000/svg" 80.12 + xmlns:xlink="http://www.w3.org/1999/xlink" 80.13 + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" 80.14 + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" 80.15 + width="744.09448819" 80.16 + height="1052.3622047" 80.17 + id="svg2" 80.18 + sodipodi:version="0.32" 80.19 + inkscape:version="0.46" 80.20 + sodipodi:docname="filelog.svg" 80.21 + sodipodi:docbase="/home/arun/hgbook/en" 80.22 + inkscape:output_extension="org.inkscape.output.svg.inkscape"> 80.23 + <defs 80.24 + id="defs4"> 80.25 + <inkscape:perspective 80.26 + sodipodi:type="inkscape:persp3d" 80.27 + inkscape:vp_x="0 : 526.18109 : 1" 80.28 + inkscape:vp_y="0 : 1000 : 0" 80.29 + inkscape:vp_z="744.09448 : 526.18109 : 1" 80.30 + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" 80.31 + id="perspective57" /> 80.32 + <marker 80.33 + inkscape:stockid="Arrow1Mend" 80.34 + orient="auto" 80.35 + refY="0.0" 80.36 + refX="0.0" 80.37 + id="Arrow1Mend" 80.38 + style="overflow:visible;"> 80.39 + <path 80.40 + id="path3128" 80.41 + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " 80.42 + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;" 80.43 + transform="scale(0.4) rotate(180) translate(10,0)" /> 80.44 + </marker> 80.45 + <linearGradient 80.46 + id="linearGradient2887"> 80.47 + <stop 80.48 + style="stop-color:#91cfcf;stop-opacity:1;" 80.49 + offset="0" 80.50 + id="stop2889" /> 80.51 + <stop 80.52 + style="stop-color:aqua;stop-opacity:0;" 80.53 + offset="1" 80.54 + id="stop2891" /> 80.55 + </linearGradient> 80.56 + <linearGradient 80.57 + id="linearGradient2795"> 80.58 + <stop 80.59 + style="stop-color:#ccc;stop-opacity:1;" 80.60 + offset="0" 80.61 + id="stop2797" /> 80.62 + <stop 80.63 + style="stop-color:#ccc;stop-opacity:0;" 80.64 + offset="1" 80.65 + id="stop2799" /> 80.66 + </linearGradient> 80.67 + <linearGradient 80.68 + inkscape:collect="always" 80.69 + xlink:href="#linearGradient2795" 80.70 + id="linearGradient3170" 80.71 + gradientUnits="userSpaceOnUse" 80.72 + gradientTransform="translate(121.2183,94.95434)" 80.73 + x1="81.322357" 80.74 + y1="404.34424" 80.75 + x2="201.52036" 80.76 + y2="373.03967" /> 80.77 + <linearGradient 80.78 + inkscape:collect="always" 80.79 + xlink:href="#linearGradient2887" 80.80 + id="linearGradient3172" 80.81 + gradientUnits="userSpaceOnUse" 80.82 + gradientTransform="translate(0,12)" 80.83 + x1="62.634491" 80.84 + y1="503.3392" 80.85 + x2="248.49242" 80.86 + y2="462.94327" /> 80.87 + <linearGradient 80.88 + inkscape:collect="always" 80.89 + xlink:href="#linearGradient2795" 80.90 + id="linearGradient3174" 80.91 + gradientUnits="userSpaceOnUse" 80.92 + gradientTransform="matrix(1.001035,0,0,0.653159,236.7075,153.0415)" 80.93 + x1="81.322357" 80.94 + y1="404.34424" 80.95 + x2="201.52036" 80.96 + y2="373.03967" /> 80.97 + <linearGradient 80.98 + inkscape:collect="always" 80.99 + xlink:href="#linearGradient2887" 80.100 + id="linearGradient3176" 80.101 + gradientUnits="userSpaceOnUse" 80.102 + gradientTransform="translate(0,12)" 80.103 + x1="62.634491" 80.104 + y1="503.3392" 80.105 + x2="248.49242" 80.106 + y2="462.94327" /> 80.107 + <linearGradient 80.108 + inkscape:collect="always" 80.109 + xlink:href="#linearGradient2795" 80.110 + id="linearGradient3208" 80.111 + gradientUnits="userSpaceOnUse" 80.112 + gradientTransform="matrix(1.001035,0,0,0.653159,236.7075,153.0415)" 80.113 + x1="81.322357" 80.114 + y1="404.34424" 80.115 + x2="201.52036" 80.116 + y2="373.03967" /> 80.117 + <linearGradient 80.118 + inkscape:collect="always" 80.119 + xlink:href="#linearGradient2887" 80.120 + id="linearGradient3210" 80.121 + gradientUnits="userSpaceOnUse" 80.122 + gradientTransform="translate(0,12)" 80.123 + x1="62.634491" 80.124 + y1="503.3392" 80.125 + x2="248.49242" 80.126 + y2="462.94327" /> 80.127 + <linearGradient 80.128 + inkscape:collect="always" 80.129 + xlink:href="#linearGradient2795" 80.130 + id="linearGradient3212" 80.131 + gradientUnits="userSpaceOnUse" 80.132 + gradientTransform="translate(121.2183,94.95434)" 80.133 + x1="81.322357" 80.134 + y1="404.34424" 80.135 + x2="201.52036" 80.136 + y2="373.03967" /> 80.137 + <linearGradient 80.138 + inkscape:collect="always" 80.139 + xlink:href="#linearGradient2887" 80.140 + id="linearGradient3214" 80.141 + gradientUnits="userSpaceOnUse" 80.142 + gradientTransform="translate(0,12)" 80.143 + x1="62.634491" 80.144 + y1="503.3392" 80.145 + x2="248.49242" 80.146 + y2="462.94327" /> 80.147 + <linearGradient 80.148 + inkscape:collect="always" 80.149 + xlink:href="#linearGradient2795" 80.150 + id="linearGradient3256" 80.151 + gradientUnits="userSpaceOnUse" 80.152 + gradientTransform="matrix(1.2343775,0,0,0.9981848,103.25588,95.681888)" 80.153 + x1="74.301666" 80.154 + y1="431.67441" 80.155 + x2="260.05884" 80.156 + y2="369.95322" /> 80.157 + <linearGradient 80.158 + inkscape:collect="always" 80.159 + xlink:href="#linearGradient2887" 80.160 + id="linearGradient3258" 80.161 + gradientUnits="userSpaceOnUse" 80.162 + gradientTransform="matrix(1.228929,0,0,0.9972824,-62.037003,13.312997)" 80.163 + x1="62.634491" 80.164 + y1="503.3392" 80.165 + x2="248.49242" 80.166 + y2="462.94327" /> 80.167 + <linearGradient 80.168 + inkscape:collect="always" 80.169 + xlink:href="#linearGradient2795" 80.170 + id="linearGradient3260" 80.171 + gradientUnits="userSpaceOnUse" 80.172 + gradientTransform="matrix(1.2300738,0,0,0.6517275,219.97511,153.61527)" 80.173 + x1="74.387527" 80.174 + y1="431.80576" 80.175 + x2="259.97339" 80.176 + y2="369.82224" /> 80.177 + <linearGradient 80.178 + inkscape:collect="always" 80.179 + xlink:href="#linearGradient2887" 80.180 + id="linearGradient3262" 80.181 + gradientUnits="userSpaceOnUse" 80.182 + gradientTransform="matrix(1.2289272,0,0,0.9972824,-62.036756,13.312985)" 80.183 + x1="62.634491" 80.184 + y1="503.3392" 80.185 + x2="248.49242" 80.186 + y2="462.94327" /> 80.187 + </defs> 80.188 + <sodipodi:namedview 80.189 + id="base" 80.190 + pagecolor="#ffffff" 80.191 + bordercolor="#666666" 80.192 + borderopacity="1.0" 80.193 + gridtolerance="10000" 80.194 + guidetolerance="10" 80.195 + objecttolerance="10" 80.196 + inkscape:pageopacity="0.0" 80.197 + inkscape:pageshadow="2" 80.198 + inkscape:zoom="1.4" 80.199 + inkscape:cx="455.8122" 80.200 + inkscape:cy="520" 80.201 + inkscape:document-units="px" 80.202 + inkscape:current-layer="layer1" 80.203 + inkscape:window-width="1280" 80.204 + inkscape:window-height="800" 80.205 + inkscape:window-x="0" 80.206 + inkscape:window-y="0" 80.207 + showgrid="false" /> 80.208 + <metadata 80.209 + id="metadata7"> 80.210 + <rdf:RDF> 80.211 + <cc:Work 80.212 + rdf:about=""> 80.213 + <dc:format>image/svg+xml</dc:format> 80.214 + <dc:type 80.215 + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> 80.216 + </cc:Work> 80.217 + </rdf:RDF> 80.218 + </metadata> 80.219 + <g 80.220 + inkscape:label="Layer 1" 80.221 + inkscape:groupmode="layer" 80.222 + id="layer1"> 80.223 + <rect 80.224 + style="opacity:1;fill:#abadf8;fill-opacity:1;stroke:#595959;stroke-width:0.93760371;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 80.225 + id="rect3180" 80.226 + width="273.81375" 80.227 + height="199.06245" 80.228 + x="369.1796" 80.229 + y="351.79019" /> 80.230 + <rect 80.231 + style="opacity:1;fill:#a2f69c;fill-opacity:1;stroke:#595959;stroke-width:0.93760341;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 80.232 + id="rect3178" 80.233 + width="273.81339" 80.234 + height="199.06233" 80.235 + x="72.699799" 80.236 + y="351.78983" /> 80.237 + <g 80.238 + id="g3144" 80.239 + transform="translate(80.467048,0.71578)"> 80.240 + <g 80.241 + id="g2940"> 80.242 + <rect 80.243 + style="fill:url(#linearGradient3260);fill-opacity:1;stroke:#000000;stroke-width:0.89536202;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 80.244 + id="rect2914" 80.245 + width="227.38896" 80.246 + height="39.500999" 80.247 + x="311.92496" 80.248 + y="395.08627" /> 80.249 + <text 80.250 + xml:space="preserve" 80.251 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 80.252 + x="323.72824" 80.253 + y="416.7626" 80.254 + id="text2918"><tspan 80.255 + sodipodi:role="line" 80.256 + id="tspan2920" 80.257 + x="323.72824" 80.258 + y="416.7626" 80.259 + style="font-family:Courier">.hg/store/data/README.i</tspan></text> 80.260 + </g> 80.261 + <g 80.262 + transform="translate(3.79093e-5,-80.1853)" 80.263 + id="g2945"> 80.264 + <g 80.265 + id="g2955"> 80.266 + <rect 80.267 + y="475.4968" 80.268 + x="15.550935" 80.269 + height="39.500999" 80.270 + width="227.17694" 80.271 + id="rect2947" 80.272 + style="fill:url(#linearGradient3262);fill-opacity:1;stroke:#000000;stroke-width:1.10706258;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> 80.273 + <text 80.274 + id="text2949" 80.275 + y="498.35123" 80.276 + x="31.230644" 80.277 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 80.278 + xml:space="preserve"><tspan 80.279 + style="font-family:Courier" 80.280 + y="498.35123" 80.281 + x="31.230644" 80.282 + id="tspan2951" 80.283 + sodipodi:role="line">README</tspan></text> 80.284 + </g> 80.285 + </g> 80.286 + <path 80.287 + inkscape:connector-type="polyline" 80.288 + id="path2960" 80.289 + d="M 242.94685,414.91115 C 242.94685,414.91115 293.61127,415.26754 310.16269,415.38633" 80.290 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1.02046943px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" 80.291 + sodipodi:nodetypes="cz" /> 80.292 + </g> 80.293 + <g 80.294 + id="g3156" 80.295 + transform="translate(80.467048,0.71578)"> 80.296 + <g 80.297 + transform="translate(116,0)" 80.298 + id="g2831"> 80.299 + <rect 80.300 + style="fill:url(#linearGradient3256);fill-opacity:1;stroke:#000000;stroke-width:1.11001658;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 80.301 + id="rect1906" 80.302 + width="228.18446" 80.303 + height="60.499123" 80.304 + x="195.52719" 80.305 + y="465.51859" /> 80.306 + <g 80.307 + id="g2803" 80.308 + transform="translate(-0.893671,1.833581)"> 80.309 + <text 80.310 + id="text1884" 80.311 + y="483.92801" 80.312 + x="208.95944" 80.313 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 80.314 + xml:space="preserve"><tspan 80.315 + style="font-family:Courier" 80.316 + y="483.92801" 80.317 + x="208.95944" 80.318 + id="tspan1886" 80.319 + sodipodi:role="line">.hg/store/data/src/hello.c.d</tspan></text> 80.320 + <text 80.321 + id="text1888" 80.322 + y="507.79309" 80.323 + x="208.95944" 80.324 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 80.325 + xml:space="preserve"><tspan 80.326 + style="font-family:Courier" 80.327 + y="507.79309" 80.328 + x="208.95944" 80.329 + id="tspan1890" 80.330 + sodipodi:role="line">.hg/store/data/src/hello.c.i</tspan></text> 80.331 + </g> 80.332 + </g> 80.333 + <g 80.334 + id="g2907"> 80.335 + <rect 80.336 + style="fill:url(#linearGradient3258);fill-opacity:1;stroke:#000000;stroke-width:1.10706329;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 80.337 + id="rect2843" 80.338 + width="227.17728" 80.339 + height="39.500999" 80.340 + x="15.550805" 80.341 + y="475.4968" /> 80.342 + <text 80.343 + xml:space="preserve" 80.344 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 80.345 + x="31.230644" 80.346 + y="498.35123" 80.347 + id="text2847"><tspan 80.348 + sodipodi:role="line" 80.349 + id="tspan2849" 80.350 + x="31.230644" 80.351 + y="498.35123" 80.352 + style="font-family:Courier">src/hello.c</tspan></text> 80.353 + </g> 80.354 + <path 80.355 + inkscape:connection-end="#g2831" 80.356 + inkscape:connection-start="#g2907" 80.357 + inkscape:connector-type="polyline" 80.358 + id="path2962" 80.359 + d="M 242.4315,495.88043 C 242.4315,495.88043 292.8861,495.99942 310.04102,496.03909" 80.360 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" 80.361 + sodipodi:nodetypes="cs" /> 80.362 + </g> 80.363 + <text 80.364 + xml:space="preserve" 80.365 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 80.366 + x="98.496666" 80.367 + y="373.96353" 80.368 + id="text3216"><tspan 80.369 + sodipodi:role="line" 80.370 + id="tspan3218" 80.371 + x="98.496666" 80.372 + y="373.96353">Directorio de trabajo</tspan></text> 80.373 + <text 80.374 + xml:space="preserve" 80.375 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 80.376 + x="391.39197" 80.377 + y="373.96353" 80.378 + id="text3228"><tspan 80.379 + sodipodi:role="line" 80.380 + id="tspan3230" 80.381 + x="391.39197" 80.382 + y="373.96353">Repositorio</tspan></text> 80.383 + </g> 80.384 +</svg>
81.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 81.2 +++ b/es/filenames.tex Thu Jan 29 22:00:07 2009 -0800 81.3 @@ -0,0 +1,344 @@ 81.4 +\chapter{Nombres de ficheros y asociación de patrones} 81.5 +\label{chap:names} 81.6 + 81.7 +Mercurial provee mecanismos que le permiten trabajar con nombres de 81.8 +ficheros en una manera consistente y expresiva. 81.9 + 81.10 +\section{Nombrado de ficheros simple} 81.11 + 81.12 +% TODO traducción literal de "under the hood". revisar 81.13 +Mercurial usa un mecanismo unificado ``bajo el capó'' para manejar 81.14 +nombres de ficheros. Cada comando se comporta de manera uniforme con 81.15 +respecto a los nombres de fichero. La manera en que los comandos 81.16 +operan con nombres de fichero es la siguiente. 81.17 + 81.18 +Si usted especifica explícitamente nombres reales de ficheros en la 81.19 +línea de comandos, Mercurial opera únicamente sobre dichos ficheros, 81.20 +como usted esperaría. 81.21 +\interaction{filenames.files} 81.22 + 81.23 +Cuando usted provee el nombre de un directorio, Mercurial interpreta 81.24 +eso como ``opere en cada fichero en este directorio y sus 81.25 +subdirectorios''. Mercurial va por todos los ficheros y subdirectorios 81.26 +de un directorio en orden alfabético. Cuando encuentra un 81.27 +subdirectorio, lo recorrerá antes de continuar con el directorio 81.28 +actual. 81.29 +\interaction{filenames.dirs} 81.30 + 81.31 +\section{Ejecución de comandos sin ningún nombre de fichero} 81.32 + 81.33 +Los comandos de Mercurial que trabajan con nombres de fichero tienen 81.34 +comportamientos por defecto adecuados cuando son utilizados sin pasar 81.35 +ningún patrón o nombre de fichero. El tipo de comportamiento depende 81.36 +de lo que haga el comando. Aquí presento unas cuantas reglas generales 81.37 +que usted puede usar para que es lo que probablemente hará un comando 81.38 +si usted no le pasa ningún nombre de fichero con el cual trabajar. 81.39 +\begin{itemize} 81.40 +\item Muchos comandos operarán sobre el directorio de trabajo 81.41 + completo. Por ejemplo, esto es lo que hace el comando 81.42 + \hgcmd{add}, 81.43 +\item Si el comando tiene efectos difíciles o incluso imposibles de 81.44 + revertir, se le obligará a usted a proveer explícitamente al menos 81.45 + % TODO revisar ese "lo proteje a usted" 81.46 + un nombre o patrón (ver más abajo). Esto lo proteje a usted de, 81.47 + por ejemplo, borrar ficheros accidentalmente al ejecutar 81.48 + \hgcmd{remove} sin ningún argumento. 81.49 +\end{itemize} 81.50 + 81.51 + 81.52 +Es fácil evitar este comportamiento por defecto, si no es el adecuado 81.53 +para usted. Si un comando opera normalmente en todo el directorio de 81.54 +trabajo, usted puede llamarlo para que trabaje sólo en el directorio 81.55 +actual y sus subdirectorio pasándole el nombre ``\dirname{.}''. 81.56 +\interaction{filenames.wdir-subdir} 81.57 + 81.58 +Siguiendo la misma línea, algunos comandos normalmente imprimen las 81.59 +rutas de ficheros con respecto a la raíz del repositorio, aún si usted 81.60 +los llama dentro de un subdirectorio. Dichos comandos imprimirán las 81.61 +rutas de los ficheros respecto al directorio en que usted se encuentra 81.62 +si se les pasan nombres explícitos. Vamos a ejecutar el comando 81.63 +\hgcmd{status} desde un subdirectorio, y a hacer que opere en el 81.64 +directorio de trabajo completo, a la vez que todas las rutas de 81.65 +ficheros se imprimen respecto a nuestro subdirectorio, pasándole la 81.66 +salida del comando \hgcmd{root}. 81.67 +\interaction{filenames.wdir-relname} 81.68 + 81.69 +\section{Reportar que está pasando} 81.70 + 81.71 +El ejemplo con el comando \hgcmd{add} en la sección anterior ilustra 81.72 +algo más que es útil acerca de los comandos de Mercurial. Si un 81.73 +comando opera en un fichero que usted no pasó explícitamente en la 81.74 +línea de comandos, usualmente se imprimirá el nombre del fichero, para 81.75 +que usted no sea sorprendido por lo que sucede. 81.76 + 81.77 +Esto es el principio de \emph{mínima sorpresa}. Si usted se ha 81.78 +referido explícitamente a un fichero en la línea de comandos, no tiene 81.79 +mucho sentido repetir esto de vuelta a usted. Si Mercurial está 81.80 +actuando en un fichero \emph{implícitamente}, porque usted no pasó 81.81 +nombres, ni directorios, ni patrones (ver más abajo), lo más seguro es 81.82 +decirle a usted qué se está haciendo. 81.83 + 81.84 +Usted puede silenciar a los comandos que se comportan de esta manera 81.85 +usando la opción \hggopt{-q}. También puede hacer que impriman el 81.86 +nombre de cada fichero, aún aquellos que usted indicó explícitamente, 81.87 +usando la opción \hggopt{-v}. 81.88 + 81.89 +\section{Uso de patrones para identificar ficheros} 81.90 + 81.91 +Además de trabajar con nombres de ficheros y directorios, Mercurial le 81.92 +permite usar \emph{patrones} para identificar ficheros. El manejo de 81.93 +patrones de Mercurial es expresivo. 81.94 + 81.95 +En sistemas tipo Unix (Linux, MacOS, etc.), el trabajo de asociar 81.96 +patrones con nombres de ficheros recae sobre el intérprete de comandos. 81.97 +En estos sistemas, usted debe indicarle explícitamente a Mercurial que 81.98 +el nombre que se le pasa es un patrón. En Windows, el intérprete no 81.99 +expande los patrones, así que Mercurial identificará automáticamente 81.100 +los nombres que son patrones, y hará la expansión necesaria. 81.101 + 81.102 +Para pasar un patrón en vez de un nombre normal en la línea de 81.103 +comandos, el mecanismo es simple: 81.104 +\begin{codesample2} 81.105 + syntax:patternbody 81.106 +\end{codesample2} 81.107 +Un patrón es identificado por una cadena de texto corta que indica qué 81.108 +tipo de patrón es, seguido por un dos puntos, seguido por el patrón en 81.109 +sí. 81.110 + 81.111 +Mercurial soporta dos tipos de sintaxis para patrones. La que se usa 81.112 +con más frecuencia se denomina \texttt{glob}\ndt{Grupo, colección, 81.113 +aglomeración.}; es el mismo tipo de asociación de patrones usado por 81.114 +el intérprete de Unix, y también debería ser familiar para los 81.115 +usuarios de la línea de comandos de Windows. 81.116 + 81.117 +Cuando Mercurial hace asociación automática de patrones en Windows, 81.118 +usa la sintaxis \texttt{glob}. Por esto, usted puede omitir el 81.119 +prefijo ``\texttt{glob:}'' en Windows, pero también es seguro usarlo. 81.120 + 81.121 +La sintaxis \texttt{re}\ndt{Expresiones regulares.} es más poderosa; 81.122 +le permite especificar patrones usando expresiones regulares, también 81.123 +conocidas como regexps. 81.124 + 81.125 +A propósito, en los ejemplos siguientes, por favor note que yo tengo 81.126 +el cuidado de rodear todos mis patrones con comillas sencillas, para 81.127 +que no sean expandidos por el intérprete antes de que Mercurial pueda 81.128 +verlos. 81.129 + 81.130 +\subsection{Patrones \texttt{glob} estilo intérprete} 81.131 + 81.132 +Este es un vistazo general de los tipos de patrones que usted puede 81.133 +usar cuando está usando asociación con patrone glob. 81.134 + 81.135 +La secuencia ``\texttt{*}'' se asocia con cualquier cadena, dentro de 81.136 +un único directorio. 81.137 +\interaction{filenames.glob.star} 81.138 + 81.139 +La secuencia ``\texttt{**}'' se asocia con cualquier cadena, y cruza los 81.140 +% TODO token 81.141 +límites de los directorios. No es una elemento estándar de los tokens 81.142 +de glob de Unix, pero es aceptado por varios intérpretes Unix 81.143 +populares, y es muy útil. 81.144 +\interaction{filenames.glob.starstar} 81.145 + 81.146 +La secuencia ``\texttt{?}'' se asocia con cualquier caracter sencillo. 81.147 +\interaction{filenames.glob.question} 81.148 + 81.149 +El caracter ``\texttt{[}'' marca el inicio de una \emph{clase de 81.150 +caracteres}. Ella se asocia con cualquier caracter sencillo dentro de 81.151 +la clase. La clase se finaliza con un caracter ``\texttt{]}''. Una 81.152 +clase puede contener múltiples \emph{rango}s de la forma 81.153 +``\texttt{a-f}'', que en este caso es una abreviación para 81.154 +``\texttt{abcdef}''. 81.155 +\interaction{filenames.glob.range} 81.156 +Si el primer caracter en aparecer después de ``\texttt{[}'' en la 81.157 +clase de caracteres es un ``\texttt{!}'', se \emph{niega} la clase, 81.158 +haciendo que se asocie con cualquier caracter sencillo que no se 81.159 +encuentre en la clase. 81.160 + 81.161 +Un ``\texttt{\{}'' marca el inicio de un grupo de subpatrones, en 81.162 +donde todo el grupo es asociado si cualquier subpatrón en el grupo 81.163 +puede ser asociado. El caracter ``\texttt{,}'' separa los subpatrones, 81.164 +y el ``\texttt{\}}'' finaliza el grupo. 81.165 +\interaction{filenames.glob.group} 81.166 + 81.167 +\subsubsection{Cuidado!} 81.168 + 81.169 +No olvide que si usted desea asocia un patrón con cualquier 81.170 +directorio, no debería usar el elemento para asociar con cualquier 81.171 +cadena ``\texttt{*}'', ya que éste sólo generará asociaciones dentro 81.172 +de un solo directorio. En vez de eso, use el caracter para asociar con 81.173 +cualquier cadena ``\texttt{**}''. Este pequeño ejemplo ilustra la 81.174 +diferencia entre los dos. 81.175 +\interaction{filenames.glob.star-starstar} 81.176 + 81.177 +\subsection{Asociación con patrones de expresiones regulares \texttt{re}} 81.178 + 81.179 +Mercurial acepta la misma sintaxis para expresiones regulares del 81.180 +lenguaje de programación Python (internamente se usa el motor de 81.181 +expresiones regulares de Python). Esta sintaxis está basada en la 81.182 +misma del lenguaje Perl, que es el dialecto más popular en uso 81.183 +(por ejemplo, también se usa en Java). 81.184 + 81.185 +No discutiré el dialecto de expresiones regulares de Mercurial en 81.186 +detalle aquí, ya que las mismas no son usadas frecuentemente. Las 81.187 +expresiones regulares al estilo Perl se encuentran documentadas 81.188 +exhaustivamente en una multitud de sitios web, y en muchos libros. 81.189 +En vez de eso, me enfocaré en unas cuantas cosas que usted debería 81.190 +conocer si tiene la necesidad de usar expresiones regulares en 81.191 +Mercurial. 81.192 + 81.193 +Una expresión regular es comparada contra un nombre de fichero 81.194 +completo, relativo a la raíz del repositorio. En otras palabras, aún 81.195 +si usted se encuentra en un subdirectorio \dirname{foo}, si desea 81.196 +asociar ficheros en este directorio, su patrón debe empezar con 81.197 +``\texttt{foo/}''. 81.198 + 81.199 +Un detalle a tener en cuenta es que, si le son familiares las 81.200 +expresiones regulares al estilo Perl, las de Mercurial están 81.201 +\emph{enraízadas}. Esto es, que la asociación de una expresión se hace 81.202 +desde el inicio de la cadena; no se buscan coincidencias dentro de la 81.203 +cadena. Para buscar coincidencias en cualquier sitio dentro de una 81.204 +cadena, empiece su patrón con un ``\texttt{.*}''. 81.205 + 81.206 +\section{Filtrado de ficheros} 81.207 + 81.208 +Mercurial no sólo le provee una variedad de formas para especificar 81.209 +ficheros; le permite limitar aún más dichos ficheros mediante el uso 81.210 +de \emph{filtros}. Los comandos que operan con nombres de fichero 81.211 +aceptan dos opciones de filtrado. 81.212 +\begin{itemize} 81.213 +\item \hggopt{-I}, o \hggopt{--include}, le permite especificar un 81.214 + patrón con el que deben coincidir los ficheros para ser 81.215 + procesados. 81.216 +\item \hggopt{-X}, o \hggopt{--exclude}, le brinda una manera de 81.217 + \emph{evitar} procesar ficheros, si coinciden con este patrón. 81.218 +\end{itemize} 81.219 +Usted puede pasar múltiples veces las opciones \hggopt{-I} y 81.220 +\hggopt{-X} en la línea de comandos, e intercalarlos como desee. 81.221 +Por defecto, Mercurial interpreta los patrones que usted pase usando 81.222 +la sintaxis glob (pero usted puede usar expresiones regulares si lo 81.223 +necesita). 81.224 + 81.225 +El filtro \hggopt{-I} puede verse como un ``procese todos los ficheros 81.226 +que coincidan con este filtro''. 81.227 +\interaction{filenames.filter.include} 81.228 +El filtro \hggopt{-X} puede verse como ``procese únicamente los 81.229 +ficheros que no coincidan con este patrón''. 81.230 +\interaction{filenames.filter.exclude} 81.231 + 81.232 +\section{Ignorar ficheros y directorios no deseados} 81.233 + 81.234 +XXX. 81.235 + 81.236 +\section{Sensibilidad a mayúsculas} 81.237 +\label{sec:names:case} 81.238 + 81.239 +Si usted está trabajando en un ambiente de desarrollo mixto que 81.240 +contiene tanto sistemas Linux (u otro Unix) y sistemas Mac o Windows, 81.241 +debería tener en mente el hecho de que ellos tratan 81.242 +%TODO FIXME seguir desde aqui, no tengo idea de como traducir case 81.243 +%sensitivity 81.244 +case (``N'' versus ``n'') of file names in incompatible ways. This is 81.245 +not very likely to affect you, and it's easy to deal with if it does, 81.246 +but it could surprise you if you don't know about it. 81.247 + 81.248 +Operating systems and filesystems differ in the way they handle the 81.249 +\emph{case} of characters in file and directory names. There are 81.250 +three common ways to handle case in names. 81.251 +\begin{itemize} 81.252 +\item Completely case insensitive. Uppercase and lowercase versions 81.253 + of a letter are treated as identical, both when creating a file and 81.254 + during subsequent accesses. This is common on older DOS-based 81.255 + systems. 81.256 +\item Case preserving, but insensitive. When a file or directory is 81.257 + created, the case of its name is stored, and can be retrieved and 81.258 + displayed by the operating system. When an existing file is being 81.259 + looked up, its case is ignored. This is the standard arrangement on 81.260 + Windows and MacOS. The names \filename{foo} and \filename{FoO} 81.261 + identify the same file. This treatment of uppercase and lowercase 81.262 + letters as interchangeable is also referred to as \emph{case 81.263 + folding}. 81.264 +\item Case sensitive. The case of a name is significant at all times. 81.265 + The names \filename{foo} and {FoO} identify different files. This 81.266 + is the way Linux and Unix systems normally work. 81.267 +\end{itemize} 81.268 + 81.269 +On Unix-like systems, it is possible to have any or all of the above 81.270 +ways of handling case in action at once. For example, if you use a 81.271 +USB thumb drive formatted with a FAT32 filesystem on a Linux system, 81.272 +Linux will handle names on that filesystem in a case preserving, but 81.273 +insensitive, way. 81.274 + 81.275 +\subsection{Almacenamiento portable y seguro de repositorios} 81.276 + 81.277 +El mecanismo de almacenamiento de los repositorios en Mercurial es 81.278 +\emph{robusto frente a sensibilidad/insensibilidad a mayúsculas}. Los nombres de 81.279 +fichero son traducidos para que puedan ser almacenados de manera 81.280 +segura tanto en sistemas sensibles como insensibles a mayúsculas. Esto 81.281 +significa que usted puede usar herramientas normales de copia de 81.282 +ficheros para transferir un repositorio Mercurial a, por ejemplo, una 81.283 +memoria USB, y trasladar de manera segura la memoria y el repositorio 81.284 +de ida y vuelta entre un Mac, un PC ejecutando Windows, y un sistema 81.285 +Linux 81.286 + 81.287 +\subsection{Detección de conflictos de mayúsculas/minúsculas} 81.288 + 81.289 +Al operar en el directorio de trabajo, Mercurial respeta la política 81.290 +de nombrado del sistema de ficheros en que se encuentre el directorio 81.291 +de trabajo. Si el sistema de ficheros conserva las diferencias entre 81.292 +mayúsculas, pero no es sensible a ellas, Mercurial tratará los nombres 81.293 +que sólo difieren en mayúsculas como uno solo y el mismo. 81.294 + 81.295 +Un aspecto importante de este enfoque es que es posible consignar un 81.296 +conjunto de cambios en un sistema de ficheros sensible a mayúsculas 81.297 +(típicamente Linux o Unix) que terminará causando problemas para 81.298 +usuarios en sistemas insensibles a mayúsculas (usualmente en Windows o 81.299 +MacOS). Si un usuario de Linux consigna cambios a dos ficheros, uno de 81.300 +ellos llamado \filename{myfile.c} y el otro llamado \filename{MyFile.C}, 81.301 +ambos serán almacenados correctamente en el repositorio. Y serán 81.302 +representados correctamente como ficheros separados, en los 81.303 +directorios de trabajo de otros usuarios de Linux. 81.304 + 81.305 +Si un usuario de Windows o Mac jalan este cambio, no tendrán problemas 81.306 +inicialmente, porque el mecanismo de almacenamiento de Mercurial es 81.307 +seguro frente a sensibilidad/insensibilidad a mayúsculas. Sin embargo, 81.308 +una vez que ellos traten de actualizar (\hgcmd{update}) el directorio 81.309 +de trabajo con ese conjunto de cambios, o hagan fusión (\hgcmd{merge}) 81.310 +con ese conjunto de cambios, Mercurial verá el conflicto entre los dos 81.311 +nombres de fichero que el sistema de ficheros trataría como el mismo, 81.312 +e impedirá que ocurra la actualización o fusión. 81.313 + 81.314 +\subsection{Arreglar un conflicto de mayúsculas/minúsculas} 81.315 + 81.316 +Si usted está usando Windows o Mac en un entorno mixto donde algunos 81.317 +de sus colaboradores están usando Linux o Unix, y Mercurial reporta un 81.318 +conflicto de mayúsculas/minúsculas cuando usted trata de actualizar 81.319 +(\hgcmd{update}) o fusionar (\hgcmd{merge}), el procedimiento para 81.320 +arreglar el problema es simple. 81.321 + 81.322 +Sólo busque un sistema Linux o Unix cercano, clone el repositorio 81.323 +problema allí, y use el comando \hgcmd{rename} de Mercurial para 81.324 +cambiar los nombres de cualquiera de los ficheros o directorios 81.325 +problemáticos para que no causen más conflictos. Consigne este cambio, 81.326 +y jálelo (\hgcmd{pull}) o empújelo (\hgcmd{push}) a su sistema Windows 81.327 +o MacOS, y actualícelo (\hgcmd{update}) a la revisión con los nombres 81.328 +que ya no generan conflictos. 81.329 + 81.330 +El conjunto de cambios con los nombres con conflictos de 81.331 +mayúsculas/minúsculas permanecerá en el historial de su proyecto, y 81.332 +usted no podrá actualizar (\hgcmd{update}) su directorio de trabajo a 81.333 +dicho conjunto de cambios en un sistema Windows o MacOS, pero puede 81.334 +continuar el desarrollo sin impedimentos. 81.335 + 81.336 +\begin{note} 81.337 + Antes de la versión~0.9.3, Mercurial no usaba un mecanismos seguro 81.338 + frente a sensibilidad/insensibilidad a mayúsculas o minúsculas, y no 81.339 + detectaba los conflictos con nombres de ficheros. Si usted está 81.340 + usando una versión más antigua de Mercurial en Windows o MacOS, le 81.341 + recomiendo enérgicamente que se actualice. 81.342 +\end{note} 81.343 + 81.344 +%%% Local Variables: 81.345 +%%% mode: latex 81.346 +%%% TeX-master: "00book" 81.347 +%%% End:
82.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 82.2 +++ b/es/fixhtml.py Thu Jan 29 22:00:07 2009 -0800 82.3 @@ -0,0 +1,1 @@ 82.4 +../en/fixhtml.py 82.5 \ No newline at end of file
83.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 83.2 +++ b/es/fixsvg Thu Jan 29 22:00:07 2009 -0800 83.3 @@ -0,0 +1,1 @@ 83.4 +../en/fixsvg 83.5 \ No newline at end of file
84.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 84.2 +++ b/es/hgbook.css Thu Jan 29 22:00:07 2009 -0800 84.3 @@ -0,0 +1,1 @@ 84.4 +../en/hgbook.css 84.5 \ No newline at end of file
85.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 85.2 +++ b/es/hgext.tex Thu Jan 29 22:00:07 2009 -0800 85.3 @@ -0,0 +1,441 @@ 85.4 +\chapter{Añadir funcionalidad con extensiones} 85.5 +\label{chap:hgext} 85.6 + 85.7 +A pesar de que el corazón de Mercurial es muy completo desde el punto 85.8 +de vista de funcionalidad, carece de características rimbombantes 85.9 +deliberadamente. Esta aproximación de preservar la simplicidad 85.10 +mantiene el programa sencillo tanto para mantenedores como para 85.11 +usuarios. 85.12 + 85.13 +Si embargo Mercurial no le cierra las posibilidades a un conjunto 85.14 +inflexible de órdenes: usted puede añadir características como 85.15 +\emph{extensiones} (aveces llamadas \emph{añadidos}\ndt{plugins}). Ya 85.16 +hemos discutido algunas de estas extensiones en capítulos anteriores: 85.17 +\begin{itemize} 85.18 +\item La sección~\ref{sec:tour-merge:fetch} cubre la extensión 85.19 + \hgext{fetch}; que combina jalar cambios y fusionarlos con los 85.20 + cambios locales en una sola orden: \hgxcmd{fetch}{fetch}. 85.21 +\item En el capítulo~\ref{chap:hook}, cubrimos muchas extensiones que 85.22 + son útiles en funcionalidades relacionadas con ganchos: Los 85.23 + \hgext{acl} añaden listas de control de acceso; \hgext{bugzilla} 85.24 + añade integración con el sistema de seguimiento de fallos Bugzilla; y 85.25 + \hgext{notify} envía notificaciones por correo de nuevos cambios. 85.26 +\item La extensión de administración de parches MQ es tan invaluable 85.27 + que amerita dos capítulos y un apéndice por sí misma. 85.28 + El capítulo~\ref{chap:mq} cubre lo básico; el 85.29 + capítulo~\ref{chap:mq-collab} discute temas avanzados; y el 85.30 + apéndice~\ref{chap:mqref} muestra en detalle cada orden. 85.31 +\end{itemize} 85.32 + 85.33 +En este capítulo cubriremos algunas extensiones adicionales 85.34 +disponibles para Mercurial, y daremos un vistazo a la maquinaria que 85.35 +necesita conocer en caso de que desee escribir una extensión. 85.36 +\begin{itemize} 85.37 +\item En la sección~\ref{sec:hgext:inotify}, discutiremos la 85.38 + posibilidad de mejorar el desempeño \emph{en gran medida} con la extensión 85.39 + \hgext{inotify}. 85.40 +\end{itemize} 85.41 + 85.42 +\section{Mejorar el desempeño con la extensión \hgext{inotify}} 85.43 +\label{sec:hgext:inotify} 85.44 + 85.45 +¿Desea lograr que las operaciones más comunmente usadas de Mercurial se 85.46 +ejecuten centenas de veces más rápido? ¡A leer! 85.47 + 85.48 +Mercurial tiene gran desempeño bajo circunstancias normales. Por 85.49 +ejemplo, cuando ejecuta la orden \hgcmd{status}, Mercurial tiene que 85.50 +revisar casi todos los ficheros y directorios en su repositorio de 85.51 +forma que pueda desplegar el estado de los ficheros. Muchas otras 85.52 +órdenes tienen que hacer tal trabajo tras bambalinas; por ejemplo la 85.53 +orden \hgcmd{diff} usa la maquinaria de estado para evitar hacer 85.54 +operaciones de comparación costosas en ficheros que obviamente no han 85.55 +cambiado. 85.56 + 85.57 +Dado que obtener el estado de los ficheros es crucial para obtener 85.58 +buen desempeño, los autores de Mercurial han optimizado este código en 85.59 +la medida de lo posible. Sin embargo, no puede obviarse el hecho de 85.60 +que cuando ejecuta \hgcmd{status}, Mercurial tendrá que hacer por lo 85.61 +menos una costosa llamada al sistema por cada fichero administrado 85.62 +para determinar si ha cambiado desde la última vez que se consignó. 85.63 +Para un repositorio suficientemente grande, puede tardar bastante 85.64 +tiempo. 85.65 + 85.66 +Para mostrar en números la magnitud de este efect, creé un repositorio 85.67 +que contenía 150.000 ficheros administrador. Tardó diez segundos para 85.68 +ejecutar \hgcmd{status}, a pesar de que \emph{ninguno} de los ficheros 85.69 +había sido modificado. 85.70 + 85.71 +Muchos sistemas operativos modernos contienen una facilidad de 85.72 +notificación de ficheros. Si un programa se registra con un servicio 85.73 +apropiado, el sistema operativo le notificará siempre que un fichero 85.74 +de interés haya sido creado, modificado o borrado. En sistemas Linux, 85.75 +el componente del núcleo que lo hace se llama \texttt{inotify}. 85.76 + 85.77 +La extensión \hgext{inotify} habla con el componente \texttt{inotify} 85.78 +del núcleo para optimizar las órdenes de \hgcmd{status}. La extensión 85.79 +tiene dos componentes. Un daemonio está en el fondo recibiendo 85.80 +notificaciones del subsistema \texttt{inotify}. También escucha 85.81 +conexiones de una orden regular de Mercurial. La extensión modifica 85.82 +el comportamiento de Mercurial de tal forma que, en lugar de revisar 85.83 +el sistema de ficheros, le pregunta al daemonio. Dado que el daemonio 85.84 +tiene información perfecta acerca del estado del repositorio, puede 85.85 +responder instantáneamente con el resultado, evitando la necesidad de 85.86 +revisar cada directorio y fichero del repositorio. 85.87 + 85.88 +Retomando los diez segundos que medí al ejecutar la orden 85.89 +\hgcmd{status} de Mercurial sobre un repositorio de 150.000 85.90 +ficheros. Con la extensión \hgext{inotify} habilitada, el tiempo se 85.91 +disipó a 0.1~seconds, un factor \emph{cien veces} más rápido. 85.92 + 85.93 +Antes de continuar, tenga en cuenta algunos detalles: 85.94 +\begin{itemize} 85.95 +\item La extensión \hgext{inotify} es específica de Linux. Porque se 85.96 + enlaza directamente con el subsistema \texttt{inotify} del núcleo 85.97 + Linux, no funciona en otros sistemas operativos. 85.98 +\item Debería funcionar en cualquier distribución Linux a partir de 85.99 + comienzos del 2005. Las distribuciones más antiguas deben tener un 85.100 + kernel sin \texttt{inotify}, o una versión de \texttt{glibc} que no 85.101 + tiene necesariamente el soporte para la interfaz. 85.102 +\item No todos los sistemas de ficheros pueden usarse con la extensión 85.103 + \hgext{inotify}. Los sistemas de ficheros tales como NFS no lo 85.104 + soportan, por ejemplo, si está corriendo Mercurial en vaios 85.105 + sistemas, montados todos sobre el mismo sistema de ficheros en red. 85.106 + El sistema \texttt{inotify} del kernel no tiene forma de saber 85.107 + acerca de los cambios hechos en otro sistema. La mayoría de 85.108 + sistemas de ficheros locales (p.e.~ext3, XFS, ReiserFS) deberían 85.109 + funcionar bien. 85.110 +\end{itemize} 85.111 + 85.112 +Hacia mayo de 2007 la extensión \hgext{inotify} no venía de forma 85.113 +predeterminada en Mercurial\ndt{Desde el 2008 para kernels 2.6 viene 85.114 + en Mercurial, pero no está activada de forma predeterminada}, y es 85.115 +un poco más compleja de activar que otras extensiones. Pero la mejora 85.116 +en el desempeño bien vale la pena! 85.117 + 85.118 +La extensión venía en dos partes: un conjunto de parches al código 85.119 +fuente de Mercurial, y una librería de interfaces de Python hacia el 85.120 +subsistema \texttt{inotify}. 85.121 +\begin{note} 85.122 + Hay \emph{dos} librerías de enlace de Python hacia \texttt{inotify}. 85.123 + Una de ellas se llama \texttt{pyinotify}, y en algunas 85.124 + distribuciones de Linux se encuentra como \texttt{python-inotify}. 85.125 + Esta es la que \emph{no} necesita, puesto que tiene muchos fallos, 85.126 + y es ineficiente para ser práctica. 85.127 +\end{note} 85.128 +Para comenzar, es mejor tener una copia de Mercurial funcional 85.129 +instalada: 85.130 +\begin{note} 85.131 + Si sigue las instrucciones a continuación, estará 85.132 + \emph{reemplazando} y sobreescribiendo cualquier instalación previa 85.133 + de Mercurial que pudiera tener, con el código de Mercurial ``más 85.134 + reciente y peligrosa''. No diga que no se le advirtio! 85.135 +\end{note} 85.136 +\begin{enumerate} 85.137 +\item Clone el repositorio de interfaz entre Python e 85.138 + \texttt{inotify}. Ármelo e instálelo: 85.139 + \begin{codesample4} 85.140 + hg clone http://hg.kublai.com/python/inotify 85.141 + cd inotify 85.142 + python setup.py build --force 85.143 + sudo python setup.py install --skip-build 85.144 + \end{codesample4} 85.145 +\item Clone el repositorio \dirname{crew} de Mercurial. Clone el 85.146 + repositorio de parches de \hgext{inotify} de forma tal que las colas 85.147 + de Mercurial puedan aplicar los parches sobre el repositorio \dirname{crew}. 85.148 + \begin{codesample4} 85.149 + hg clone http://hg.intevation.org/mercurial/crew 85.150 + hg clone crew inotify 85.151 + hg clone http://hg.kublai.com/mercurial/patches/inotify inotify/.hg/patches 85.152 + \end{codesample4} 85.153 +\item Asegúrese de instalar la extensión Colas de Mercurial 85.154 + \hgext{mq} y que estén habilitadas. Si nunca ha usado MQ, lea la 85.155 + sección~\ref{sec:mq:start} para poder comenzar rápidamente. 85.156 +\item Vaya al repositorio de \dirname{inotify} y aplique todos los 85.157 + parches de \hgext{inotify} con la opción \hgxopt{mq}{qpush}{-a} de 85.158 + la orden \hgxcmd{mq}{qpush}. 85.159 + \begin{codesample4} 85.160 + cd inotify 85.161 + hg qpush -a 85.162 + \end{codesample4} 85.163 + Si obtiene un mensaje de error de \hgxcmd{mq}{qpush}, no debería 85.164 + continuar. Mejor pida ayuda. 85.165 +\item Arme e instale la versión parchada de Mercurial. 85.166 + \begin{codesample4} 85.167 + python setup.py build --force 85.168 + sudo python setup.py install --skip-build 85.169 + \end{codesample4} 85.170 +\end{enumerate} 85.171 +Una vez que haya armado una versión funcional parchada de Mercurial, 85.172 +todo lo que necesita es habilitar la extensión \hgext{inotify} 85.173 +colocando una entrada en su \hgrc. 85.174 +\begin{codesample2} 85.175 + [extensions] 85.176 + inotify = 85.177 +\end{codesample2} 85.178 +Cuando la extensión \hgext{inotify} esté habilitada, Mercurial 85.179 +iniciará transparente y automáticamente el daemonio de estado la 85.180 +primera vez que ejecute un comando que requiera estado del 85.181 +repositorio. Ejecuta un daemonio de estado por repositorio. 85.182 + 85.183 +El daemonio de estado se inicia silenciosamente y se ejecuta en el 85.184 +fondo. Si mira a la lista de procesos en ejecución después de 85.185 +habilitar la extensión \hgext{inotify} y ejecuta unos pocos comandos 85.186 +en diferentes repositorios, verá que hay algunos procesos de 85.187 +\texttt{hg} por ahí, esperando actualizaciones del kernel y 85.188 +solicitudes de Mercurial. 85.189 + 85.190 +La primera vez que ejecuta un comando de Mercurial en un repositorio 85.191 +cuando tiene la extensión \hgext{inotify} habilitada, correrá casi con 85.192 +el mismo desempeño que una orden usual de Mercurial. Esto es debido a 85.193 +que el estado del daemonio necesita aplicar una búsqueda normal sobre 85.194 +el estado para poder tener una línea de partida frente a la cual 85.195 +aplicar posteriormente actualizaciones del núcleo. De todas formas, 85.196 +\emph{todo} comando posterior que haga cualquier clase de revisión del 85.197 +estado debería ser notablemente más rápido en repositorios con incluso 85.198 +un tamaño modesto. Aún mejor, a medida que su repositorio sea más 85.199 +grande, mejor desempeño verá. El daemonio \hgext{inotify} hace 85.200 +operaciones de estado de forma casi instantánea en repositorios de 85.201 +todos los tamaños! 85.202 + 85.203 +Si lo desea, puede iniciar manualmente un daemonio de estado con la orden 85.204 +\hgxcmd{inotify}{inserve}. Esto le da un control un poco más fino 85.205 +acerca de cómo debería ejecutarse el daemonio. Esta orden solamente 85.206 +estará disponible cuando haya habilitado la extensión \hgext{inotify}. 85.207 + 85.208 +Cuando esté usando la extensión \hgext{inotify}, 85.209 +\emph{no debería ver diferencia} en el comportamiento de Mercurial, 85.210 +con la única excepción de que los comandos relacionados con el estado 85.211 +deberían ejectuarse mucho más rápido que como solían hacerlo. Debería 85.212 +esperar específicamente que las órdenes no deberían ofrecer salidas 85.213 +distintas; ni ofrecer resultados diferentes. Si alguna de estas 85.214 +situaciones ocurre, por favor reporte el fallo. 85.215 + 85.216 +\section{Soporte flexible de diff con la extensión \hgext{extdiff}} 85.217 +\label{sec:hgext:extdiff} 85.218 + 85.219 +La orden predeterminada \hgcmd{diff} de Mercurial despliega diffs en 85.220 +texto plano unificadas. 85.221 +\interaction{extdiff.diff} 85.222 +Si dese emplear una herramienta externa para desplegar las 85.223 +modificaciones, querrá usar la extensión \hgext{extdiff}. Esta le 85.224 +permitirá usar por ejemplo una herramienta gráfica de diff. 85.225 + 85.226 +La extensión \hgext{extdiff} viene con Mercurial, y es fácil 85.227 +configurar. En la sección \rcsection{extensions} de su \hgrc, 85.228 +basta con añadir una entrada de una línea para habilitar la extensión. 85.229 +\begin{codesample2} 85.230 + [extensions] 85.231 + extdiff = 85.232 +\end{codesample2} 85.233 +Esto introduce una orden llamada \hgxcmd{extdiff}{extdiff}, que de 85.234 +forma predeterminada usa su orden del sistema \command{diff} para 85.235 +generar un diff unificado de la misma forma que lo hace el comando 85.236 +predeterminado \hgcmd{diff}. 85.237 +\interaction{extdiff.extdiff} 85.238 +El resultado no será exactamente el mismo que con la orden interna 85.239 +\hgcmd{diff}, puesto que la salida de \command{diff} varía de un 85.240 +sistema a otro, incluso pasando las mismas opciones. 85.241 + 85.242 +Como lo indican las líneas``\texttt{making snapshot}'', la orden 85.243 +\hgxcmd{extdiff}{extdiff} funciona creando dos instantáneas de su 85.244 +árbol de fuentes. La primera instantánea es la revisión fuente; la 85.245 +segunda es la revisión objetivo del directorio de trabajo. La orden 85.246 +\hgxcmd{extdiff}{extdiff} genera estas instantáneas en un directorio 85.247 +temporal, pasa el nombre de cada directorio a un visor de diffs 85.248 +temporal y borra los directorios temporales. Por cuestiones de 85.249 +eficiencia solamente genera instantáneas de los directorios y ficheros 85.250 +que han cambiado entre dos revisiones. 85.251 + 85.252 +Los nombres de los directorios de instantáneas tienen los mismos 85.253 +nombres base de su repositorio. Si su repositorio tiene por ruta 85.254 +\dirname{/quux/bar/foo}, \dirname{foo} será el nombre de cada 85.255 +instantánea de directorio. Cada instantánea de directorio tiene sus 85.256 +identificadores de conjuntos de cambios al final del nombre en caso de 85.257 +que sea apropiado. Si una instantánea viene de la revisión 85.258 +\texttt{a631aca1083f}, el directorio se llamará 85.259 +\dirname{foo.a631aca1083f}. Una instantánea del directorio de trabajo 85.260 +no tendrá el identificador del conjunto de cambios, y por lo tanto 85.261 +será solamente \dirname{foo} en este ejemplo. Para ver cómo luce en 85.262 +la práctica, veamos de nuevo el ejemplo \hgxcmd{extdiff}{extdiff} 85.263 +antes mencionado. Tenga en cuenta que los diffs tienen los nombres de 85.264 +las instantáneas de directorio dentro de su encabezado. 85.265 + 85.266 +La orden \hgxcmd{extdiff}{extdiff} acepta dos opciones importantes. 85.267 +La opción \hgxopt{extdiff}{extdiff}{-p} le permite elegir un programa 85.268 +para ver las diferencias, en lugar de \command{diff}. Con la opción 85.269 +\hgxopt{extdiff}{extdiff}{-o} puede cambiar las opciones que 85.270 +\hgxcmd{extdiff}{extdiff} pasa a tal programa (de forma predeterminada 85.271 +las opciones son``\texttt{-Npru}'', que tienen sentido únicamente si 85.272 +está usando \command{diff}). En otros aspectos, la orden 85.273 +\hgxcmd{extdiff}{extdiff} actúa de forma similar a como lo hace la 85.274 +orden \hgcmd{diff} de Mercurial: usted usa los mismos nombres de 85.275 +opciones, sintaxis y argumentos para especificar las revisiones y los 85.276 +ficheros que quiere, y así sucesivamente. 85.277 + 85.278 +Por ejemplo, para ejecutar la orden usual del sistema \command{diff}, 85.279 +para lograr que se generen diferencias de contexto (con la opción 85.280 +\cmdopt{diff}{-c}) en lugar de diferencias unificadas, y cinco líneas 85.281 +de contexto en lugar de las tres predeterminadas (pasando \texttt{5} 85.282 +como argumento a la opción \cmdopt{diff}{-C}). 85.283 +\interaction{extdiff.extdiff-ctx} 85.284 + 85.285 +Es sencillo lanzar unas herramienta usual de diferencias. Para lanzar 85.286 +el visor \command{kdiff3}: 85.287 +\begin{codesample2} 85.288 + hg extdiff -p kdiff3 -o '' 85.289 +\end{codesample2} 85.290 + 85.291 +Si su orden para visualizar diferencias no puede tratar con 85.292 +directorios, puede usar un poco de scripting para lograrlo. Un 85.293 +ejemplo de un script con la extensión \hgext{mq} junto con la orden 85.294 +\command{interdiff} está en la sección~\ref{mq-collab:tips:interdiff}. 85.295 + 85.296 +\subsection{Definición de alias de comandos} 85.297 + 85.298 +Acordarse de todas las opciones de las órdenes 85.299 +\hgxcmd{extdiff}{extdiff} y el visor de diferencias de su preferencia 85.300 +puede ser dispendioso, y por lo tanto la extensión \hgext{extdiff} le 85.301 +permite definir \emph{nuevas} órdenes que invocarán su visor de 85.302 +diferencias con las opciones exactas. 85.303 + 85.304 +Basta con editar su fichero \hgrc, y añadir una sección llamada 85.305 +\rcsection{extdiff}. Dentro de esta sección puede definir varias 85.306 +órdenes. Mostraremos como añadir la orden \texttt{kdiff3}. Después de 85.307 +definido, puede teclear ``\texttt{hg kdiff3}'' y la extensión a 85.308 +\hgext{extdiff} ejecutará la orden \command{kdiff3}. 85.309 +\begin{codesample2} 85.310 + [extdiff] 85.311 + cmd.kdiff3 = 85.312 +\end{codesample2} 85.313 +Si deja vacía la porción derecha de la definición, como en el ejemplo, 85.314 +la extensión \hgext{extdiff} usa el nombre de la orden se definirá 85.315 +como el nombre del programa externo a ejecutar. Pero tales nombres no 85.316 +tienen por qué ser iguales. Definimos ahora la orden llamada 85.317 + ``\texttt{hg wibble}'', que ejecuta \command{kdiff3}. 85.318 +\begin{codesample2} 85.319 + [extdiff] 85.320 + cmd.wibble = kdiff3 85.321 +\end{codesample2} 85.322 + 85.323 +También puede especificar las opciones predeterminadas con las cuales 85.324 +desea invocar el visor de diferencias. Se usa el prefijo ``\texttt{opts.}'', 85.325 +seguido por el nombre de la orden a la cual se aplican las opciones. 85.326 +En este ejemplos se define la orden ``\texttt{hg vimdiff}'' que 85.327 +ejecuta la extensión \texttt{DirDiff} del editor \command{vim}. 85.328 +\begin{codesample2} 85.329 + [extdiff] 85.330 + cmd.vimdiff = vim 85.331 + opts.vimdiff = -f '+next' '+execute "DirDiff" argv(0) argv(1)' 85.332 +\end{codesample2} 85.333 + 85.334 +\section{Uso de la extensión \hgext{transplant} para seleccionar} 85.335 +\label{sec:hgext:transplant} 85.336 + 85.337 +Need to have a long chat with Brendan about this. 85.338 + 85.339 +\section{Enviar cambios vía correo electrónico con la extensión \hgext{patchbomb}} 85.340 +\label{sec:hgext:patchbomb} 85.341 + 85.342 +Varios proyectos tienen la cultura de ``revisión de cambios'', en la 85.343 +cual la gente envía sus modificaciones a una lista de correo para que 85.344 +otros las lean y comenten antes de consignar la versión final a un 85.345 +repositorio compartido. Algunos proyectos tienen personas que actúan 85.346 +como cancerberos; ellos aplican los cambios de otras personas a un 85.347 +repositorio para aquellos que no tienen acceso. 85.348 + 85.349 +Mercurial facilita enviar cambios por correo para revisión o 85.350 +aplicación gracias a su extensión \hgext{patchbomb}. La extensión es 85.351 +tan popular porque los cambios se formatean como parches y es usual 85.352 +que se envía un conjunto de cambios por cada correo. Enviar una gran 85.353 +cantidad de cambios por correos se llama por tanto ``bombardear'' el 85.354 +buzón de entrada del destinatario, de ahí su nombre ``bombardeo de 85.355 +parches''. 85.356 + 85.357 +Como es usual, la configuración básica de la extensión 85.358 +\hgext{patchbomb} consta de una o dos líneas en su \hgrc. 85.359 +\begin{codesample2} 85.360 + [extensions] 85.361 + patchbomb = 85.362 +\end{codesample2} 85.363 +Cuando haya habilitado la extensión, dispondrá de una nueva orden, 85.364 +llamada \hgxcmd{patchbomb}{email}. 85.365 + 85.366 +La forma mejor y más segura para invocar la orden 85.367 +\hgxcmd{patchbomb}{email} es ejecutarla \emph{siempre} con la opción 85.368 +\hgxopt{patchbomb}{email}{-n}; que le mostrará lo que la orden 85.369 +\emph{enviaría}, sin enviar nada. Una vez que haya dado un vistazo a 85.370 +los cambios y verificado que está enviando los correctos, puede volver 85.371 +a ejecutar la misma orden, sin la opción \hgxopt{patchbomb}{email}{-n}. 85.372 + 85.373 +La orden \hgxcmd{patchbomb}{email} acepta la misma clase de sintaxis 85.374 +de revisiones como cualquier otra orden de Mercurial. Por ejemplo, 85.375 +enviará todas las revisiones entre la 7 y la \texttt{punta}, inclusive. 85.376 +\begin{codesample2} 85.377 + hg email -n 7:tip 85.378 +\end{codesample2} 85.379 +También puede especificar un \emph{repositorio} para comparar. Si 85.380 +indica un repositoro sin revisiones, la orden \hgxcmd{patchbomb}{email} 85.381 +enviará todas las revisiones en el repositorio local que no están 85.382 +presentes en el repositorio remoto. Si especifica revisiones 85.383 +adicionalmente o el nombre de una rama (la última con la opción 85.384 +\hgxopt{patchbomb}{email}{-b}), respetará las revisiones enviadas. 85.385 + 85.386 +Ejecutar la orden \hgxcmd{patchbomb}{email} sin los nombres de 85.387 +aquellas personas a las cuales desea enviar el correo es completamente 85.388 +seguro: si lo hace, solicitará tales valores de forma interactiva. 85.389 +(Si está usando Linux o un sistema tipo Unix, tendrá capacidades 85.390 +estilo--\texttt{readline} aumentadas cuando ingrese tales encabezados, 85.391 +lo cual es sumamente útil.) 85.392 + 85.393 +Cuando envíe una sola revisión, la orden \hgxcmd{patchbomb}{email} 85.394 +de forma predeterminada usará la primera línea de descripción del 85.395 +conjunto de cambios como el tema del único mensaje que se enviará. 85.396 + 85.397 +Si envía varias revisiones, la orden \hgxcmd{patchbomb}{email} enviará 85.398 +normalmente un mensaje por conjunto de cambios. Colocará como 85.399 +prefacio un mensaje introductorio en el cual usted debería describir 85.400 +el propósito de la serie de cambios que está enviando. 85.401 + 85.402 +\subsection{Cambiar el comportamiento de las bombas de parches} 85.403 + 85.404 +Cada proyecto tiene sus propias convenciones para enviar cambios en un 85.405 +correo electrónico; la extensión \hgext{patchbomb} intenta acomodarse 85.406 +a diferentes variaciones gracias a las opciones de la línea de órdenes: 85.407 +\begin{itemize} 85.408 +\item Puede escribir un tema para el mensaje introductorio en la línea 85.409 + de órdenes con la opciń \hgxopt{patchbomb}{email}{-s}. Toma un 85.410 + argumento: el tema del mensaje a usar. 85.411 +\item Para cambiar el correo electrónico del campo del cual se 85.412 + origina, use la opción \hgxopt{patchbomb}{email}{-f}. Toma un 85.413 + argumento, el correo electrónico a usar. 85.414 +\item El comportamiento predeterminado es enviar diferencias 85.415 + unificadas (consulte la sección~\ref{sec:mq:patch} si desea una 85.416 + descripción del formato), una por mensaje. Puede enviar un conjunto 85.417 + binario\ndt{binary bundle} con la opción \hgxopt{patchbomb}{email}{-b}. 85.418 +\item Las diferencias unificadas están precedidas por un encabezado de 85.419 + metadatos. Puede omitirlo, y enviar diferencias sin adornos con la 85.420 + opción \hgxopt{patchbomb}{email}{--plain}. 85.421 +\item Las diferencias usualmente se envían ``en línea'', como parte 85.422 + del cuerpo del mensaje con la descripción del parche. Que facilita a 85.423 + a la mayor cantidad de lectores citar y responder partes de un diff, 85.424 + dado que algunos clientes de correo solamente citarán la primera 85.425 + parte MIME del cuerpo de un mensaje. Si prefiere enviar la 85.426 + descripción y el diff en partes separadas del cuerpo, use la opción 85.427 + \hgxopt{patchbomb}{email}{-a}. 85.428 +\item En lugar de enviar mensajes de correo puede escribirlos a un 85.429 + fichero con formato-\texttt{mbox}- con la opción 85.430 + \hgxopt{patchbomb}{email}{-m}. La opción recibe un argumento, el 85.431 + nombre del fichero en el cual escribir. 85.432 +\item Si desea añadir un resumen con formato-\command{diffstat} en 85.433 + cada parche, y uno como mensaje introductorio, use la opción 85.434 + \hgxopt{patchbomb}{email}{-d}. La orden \command{diffstat} 85.435 + despliega una tabla que contiene el nombre de cada fichero parchado, 85.436 + el número de líneas afectadas, y un historgrama mostrando cuánto ha 85.437 + sido modificado cada fichero. Lo cual ofrece a los lectores una 85.438 + mirada cuantitativa de cuan complejo es el parche. 85.439 +\end{itemize} 85.440 + 85.441 +%%% Local Variables: 85.442 +%%% mode: latex 85.443 +%%% TeX-master: "00book" 85.444 +%%% End:
86.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 86.2 +++ b/es/hook.tex Thu Jan 29 22:00:07 2009 -0800 86.3 @@ -0,0 +1,1568 @@ 86.4 +\chapter{Manejo de eventos en repositorios mediante ganchos} 86.5 +\label{chap:hook} 86.6 + 86.7 +Mercurial ofrece un poderoso mecanismo para permitirle a usted 86.8 +automatizar la ejecución de acciones en respuesta a eventos que 86.9 +ocurran en un repositorio. En algunos casos, usted puede controlar 86.10 +incluso la respuesta de Mercurial a dichos eventos. 86.11 + 86.12 +Mercurial usa el término \emph{gancho} para identificar estas 86.13 +acciones. Los ganchos son conocidos como ``disparadores'' en algunos 86.14 +sistemas de control de revisiones, pero los dos nombres se refieren al 86.15 +mismo concepto. 86.16 + 86.17 +\section{Vistazo general de ganchos en Mercurial} 86.18 + 86.19 +A continuación se encuentra una breve lista de los ganchos que 86.20 +Mercurial soporta. Volveremos a cada uno de estos ganchos con más 86.21 +detalle después, en la sección~\ref{sec:hook:ref}. 86.22 + 86.23 +\begin{itemize} 86.24 +\item[\small\hook{changegroup}] Es ejecutado luego de que un grupo de 86.25 + conjuntos de cambios ha sido traído al repositorio desde algún 86.26 + otro sitio. 86.27 +\item[\small\hook{commit}] Es ejecutado después de la creación de 86.28 + un conjunto de cambios en el repositorio local. 86.29 +\item[\small\hook{incoming}] Es ejecutado una vez por cada conjunto de 86.30 + cambios traído al repositorio desde otra ubicación. Note la 86.31 + diferencia respecto al gancho \hook{changegroup}, que es ejecutado 86.32 + una vez por cada \emph{grupo} de conjuntos de cambios que se 86.33 + traiga. 86.34 +\item[\small\hook{outgoing}] Es ejecutado luego de que un grupo de 86.35 + conjuntos de cambios ha sido transmitido desde el repositorio. 86.36 +\item[\small\hook{prechangegroup}] Es ejecutado antes de iniciar la 86.37 + recepción de un grupo de conjuntos de cambios en el repositorio. 86.38 +\item[\small\hook{precommit}] De control. Es ejecutado antes de 86.39 + iniciar una consignación. 86.40 +\item[\small\hook{preoutgoing}] De control. Es ejecutado antes de 86.41 + iniciar la transmisión de un grupo de conjuntos de cambios desde 86.42 + el repositorio. 86.43 +\item[\small\hook{pretag}] De control. Es ejecutado antes de crear una 86.44 + etiqueta. 86.45 +\item[\small\hook{pretxnchangegroup}] De control. Es ejecutado después 86.46 + de haber recibido un grupo de conjuntos de cambios en el 86.47 + repositorio local, pero antes de que la transacción se complete y 86.48 + los cambios sean permanentes dentro del repositorio. 86.49 +\item[\small\hook{pretxncommit}] De control. Es ejecutado luego de la 86.50 + creación de un conjunto de cambios en el repositorio local, pero 86.51 + antes de que la transacción que hace permanente el cambio sea 86.52 + completada. 86.53 +\item[\small\hook{preupdate}] De control. Es ejecutado antes de 86.54 + iniciar una actualización o fusión en el directorio de trabajo. 86.55 +\item[\small\hook{tag}] Es ejecutado después de la creación de una 86.56 + etiqueta. 86.57 +\item[\small\hook{update}] Es ejecutado después de que termina una 86.58 + actualización o una fusión. 86.59 +\end{itemize} 86.60 +Cada uno de los ganchos cuya descripción empieza con la frase 86.61 +``de control'' tiene la facultad de determinar si una actividad puede 86.62 +continuar. Si el gancho se ejecuta con éxito, la actividad puede 86.63 +continuar; si falla, o bien la actividad no es permitida, o se 86.64 +deshacen los cambios que se puedan haber llevado a cabo, dependiendo 86.65 +del gancho involucrado. 86.66 + 86.67 +\section{Ganchos y seguridad} 86.68 + 86.69 +\subsection{Los ganchos se ejecutan con sus privilegios de usuario} 86.70 + 86.71 +Cuando usted ejecuta un comando de Mercurial en un repositorio, y el 86.72 +comando causa la ejecución de un gancho, dicho gancho se ejecuta en 86.73 +\emph{su} sistema, en \emph{su} cuenta de usuario, con \emph{sus} 86.74 +privilegios. Ya que los ganchos son elementos arbitrarios de código 86.75 +ejecutable, usted debería tratarlos con un nivel adecuado de 86.76 +desconfianza. No instale un gancho a menos en que confíe en quien lo 86.77 +creó y en lo que el gancho hace. 86.78 + 86.79 +En algunos casos, usted puede estar expuesto a ganchos que usted no 86.80 +%TODO acá introduzco algo de texto por mi cuenta, por claridad 86.81 +instaló. Si usted usa Mercurial en un sistema extraño, tenga en cuenta 86.82 +que Mercurial ejecutará los ganchos definidos en el fichero \hgrc. 86.83 + 86.84 +Si está trabajando con un repositorio propiedad de otro usuario, 86.85 +Mercurial podrá ejecutar los ganchos definidos en el repositorio de 86.86 +dicho usuario, pero los ejecutará como ``usted''. Por ejemplo, si 86.87 +usted jala (\hgcmd{pull}) desde ese repositorio, y el 86.88 +\sfilename{.hg/hgrc} define un gancho saliente (\hook{outgoing}), 86.89 +dicho gancho se ejecuta bajo su cuenta de usuario, aun cuando usted no 86.90 +es el propietario del repositorio. 86.91 + 86.92 +\begin{note} 86.93 + Esto sólo aplica si usted está jalando desde un repositorio en un 86.94 + sistema de ficheros local o de red. Si está jalando a través de http 86.95 + o ssh, cualquier gancho saliente (\hook{outgoing}) se ejecutará bajo 86.96 + la cuenta que está ejecutando el proceso servidor, en el servidor. 86.97 +\end{note} 86.98 + 86.99 +XXX Para ver qué ganchos han sido definidos en un repositorio, use el 86.100 +comando \hgcmdargs{config}{hooks}. Si usted está trabajando en un 86.101 +repositorio, pero comunicándose con otro que no le pertenece 86.102 +(por ejemplo, usando \hgcmd{pull} o \hgcmd{incoming}), recuerde que 86.103 +los ganchos que debe considerar son los del otro repositorio, no los 86.104 +del suyo. 86.105 + 86.106 +\subsection{Los ganchos no se propagan} 86.107 + 86.108 +En Mercurial, no se hace control de revisiones de los ganchos, y no se 86.109 +propagan cuando usted clona, o jala de, un repositorio. El motivo para 86.110 +esto es simple: un gancho es código ejecutable arbitrario. Se ejecuta 86.111 +bajo su identidad, con su nivel de privilegios, en su máquina. 86.112 + 86.113 +Sería extremadamente descuidado de parte de cualquier sistema 86.114 +distribuido de control de revisiones el implementar control de 86.115 +revisiones para ganchos, ya que esto ofrecería maneras fácilmente 86.116 +%TODO subvertir 86.117 +aprovechables de subvertir las cuentas de los usuarios del sistema de 86.118 +control de revisiones. 86.119 + 86.120 +Ya que Mercurial no propaga los ganchos, si usted está colaborando con 86.121 +otras personas en un proyecto común, no debería asumir que ellos están 86.122 +usando los mismos ganchos para Mercurial que usted usa, o que los de 86.123 +ellos están configurado correctamente. Usted debería documentar los 86.124 +ganchos que usted espera que la gente use. 86.125 + 86.126 +En una intranet corporativa, esto es algo más fácil de manejar, ya que 86.127 +usted puede, por ejemplo, proveer una instalación ``estándar'' de 86.128 +Mercurial en un sistema de ficheros NFS, y usar un fichero \hgrc\ 86.129 +global para definir los ganchos que verán todos los usuarios. Sin 86.130 +embargo, este enfoque tiene sus límites; vea más abajo. 86.131 + 86.132 +\subsection{Es posible hacer caso omiso de los ganchos} 86.133 + 86.134 +Mercurial le permite hacer caso omiso de la deficinión de un gancho, 86.135 +a través de la redefinición del mismo. Usted puede deshabilitar el 86.136 +gancho fijando su valor como una cadena vacía, o cambiar su 86.137 +comportamiento como desee. 86.138 + 86.139 +Si usted instala un fichero \hgrc\ a nivel de sistema o sitio completo 86.140 +que define algunos ganchos, debe entender que sus usuarios pueden 86.141 +deshabilitar o hacer caso omiso de los mismos. 86.142 + 86.143 +\subsection{Asegurarse de que ganchos críticos sean ejecutados} 86.144 + 86.145 +Algunas veces usted puede querer hacer respetar una política, y no 86.146 +permitir que los demás sean capaces de evitarla. Por ejemplo, usted 86.147 +puede tener como requerimiento que cada conjunto de cambios debe pasar 86.148 +un riguroso conjunto de pruebas. Definir este requerimientos a través 86.149 +de un gancho en un fichero \hgrc\ global no servirá con usuarios 86.150 +remotos en computadoras portátiles, y por supuesto que los usuarios 86.151 +locales pueden evitar esto a voluntad haciendo caso omiso del gancho. 86.152 + 86.153 +En vez de eso, usted puede definir las políticas para usar Mercurial 86.154 +de tal forma que se espere que los usuarios propaguen los cambios a 86.155 +través de un servidor ``canónico'' bien conocido que usted ha 86.156 +asegurado y configurado apropiadamente. 86.157 + 86.158 +Una manera de hacer esto es a través de una combinación de ingeniería 86.159 +social y tecnología. Cree una cuenta de acceso restringido; los 86.160 +usuarios pueden empujar cambios a través de la red a los repositorios 86.161 +administrados por esta cuenta, pero no podrán ingresar a dicha cuenta 86.162 +para ejecutar órdenes en el intérprete de comandos. En este escenario, 86.163 +un usuario puede enviar un conjunto de cambios que contenga la 86.164 +porquería que él desee. 86.165 + 86.166 +Cuando alguien empuja un conjunto de cambios al servidor del que todos 86.167 +jalan, el servidor probará el conjunto de cambios antes de aceptarlo 86.168 +como permanente, y lo rechazará si no logra pasar el conjunto de 86.169 +pruebas. Si la gente sólo jala cambios desde este servidor de filtro, 86.170 +servirá para asegurarse de que todos los cambios que la gente jala han 86.171 +sido examinados automáticamente 86.172 + 86.173 +\section{Precauciones con ganchos \texttt{pretxn} en un repositorio de 86.174 +acceso compartido} 86.175 + 86.176 +Si usted desea usar ganchos para llevar a cabo automáticamente algún 86.177 +trabajo en un repositorio al que varias personas tienen acceso 86.178 +compartido, debe tener cuidado con la forma de hacerlo. 86.179 + 86.180 +Mercurial sólo bloquea un repositorio cuando está escribiendo al 86.181 +mismo, y sólo las partes de Mercurial que escriben al repositorio le 86.182 +prestan atención a los bloqueos. Los bloqueos de escritura son 86.183 +necesarios para evitar que múltiples escritores simultáneos 86.184 +interfieran entre sí, corrompiendo el repositorio. 86.185 + 86.186 +Ya que Mercurial tiene cuidado con el orden en que lee y escribe 86.187 +datos, no necesita adquirir un bloqueo cuando desea leer datos del 86.188 +repositorio. Las partes de Mercurial que leen del repositorio nunca le 86.189 +prestan atención a los bloqueos. Este esquema de lectura libre de 86.190 +bloqueos incremententa en gran medida el desempeño y la concurrencia. 86.191 + 86.192 +Sin embargo, para tener un gran desempeño es necesario hacer 86.193 +sacrificios, uno de los cuales tiene el potencial de causarle 86.194 +problemas a menos de que usted esté consciente de él. Describirlo 86.195 +requiere algo de detalle respecto a cómo Mercurial añade conjuntos de 86.196 +cambios al repositorio y cómo lee esos cambios de vuelta. 86.197 + 86.198 +Cuando Mercurial \emph{escribe} metadatos, los escribe directamente en 86.199 +el fichero de destino. Primero escribe los datos del fichero, luego 86.200 +los datos del manifiesto (que contienen punteros a los nuevos datos 86.201 +del fichero), luego datos de la bitácora de cambios (que contienen 86.202 +punteros a los nuevos datos del manifiesto). Antes de la primera 86.203 +escritura a cada fichero, se guarda un registro de dónde estaba el 86.204 +final de fichero en su registro de transacciones. Si la transacción 86.205 +debe ser deshecha, Mercurial simplemente trunca cada fichero de vuelta 86.206 +al tamaño que tenía antes de que empezara la transacción. 86.207 + 86.208 +Cuando Mercurial \emph{lee} metadatos, lee la bitácora de cambios 86.209 +primero, y luego todo lo demás. Como un lector sólo accederá a las 86.210 +partes del manifiesto o de los metadatos de fichero que él puede ver 86.211 +en la bitácora de cambios, nunca puede ver datos parcialmente 86.212 +escritos. 86.213 + 86.214 +Algunos ganchos de control (\hook{pretxncommit} y 86.215 +\hook{pretxnchangegroup}) se ejecutan cuando una transacción está casi 86.216 +completa. Todos los metadatos han sido escritos, pero Mercurial aún 86.217 +puede deshacer la transacción y hacer que los datos recién escritos 86.218 +desaparezcan. 86.219 + 86.220 +Si alguno de estos ganchos permanece en ejecución por mucho tiempo, 86.221 +abre una ventana de tiempo en la que un lector puede ver los metadatos 86.222 +de conjuntos de cambios que aún no son permanentes y que no debería 86.223 +considerarse que estén ``realmante ahí''. Entre más tiempo tome la 86.224 +ejecución del gancho, más tiempo estará abierta esta ventana. 86.225 + 86.226 +\subsection{Ilustración del problema} 86.227 + 86.228 +En principio, un buen uso del gancho \hook{pretxnchangegroup} sería 86.229 +ensamblar y probar automáticamente todos los cambios entrantes antes 86.230 +de que sean aceptados en un repositorio central. Esto le permitiría a 86.231 +usted garantizar que nadie pueda empujar cambios que ``rompan el 86.232 +ensamblaje''. Pero si un cliente puede jalar cambios mientras están 86.233 +siendo probados, la utilidad de esta prueba es nula; alguien confiado 86.234 +puede jalar cambios sin probar, lo que potencialmente podría romper su 86.235 +proceso de ensamblaje. 86.236 + 86.237 +La respuesta técnica más segura frente a este retos es montar dicho 86.238 +repositorio ``guardián'' como \emph{unidireccional}. Permita que 86.239 +reciba cambios desde el exterior, pero no permita que nadie jale 86.240 +cambios de él (use el gancho \hook{preoutgoing} para bloquear esto). 86.241 +Configure un gancho \hook{changegroup} para que si el ensamblaje o 86.242 +prueba tiene éxito, el gancho empuje los nuevos cambios a otro 86.243 +repositorio del que la gente \emph{pueda} jalar. 86.244 + 86.245 +En la práctica, montar un cuello de botella centralizado como éste a 86.246 +menudo no es una buena idea, y la visibilidad de las transacciones no 86.247 +tiene nada que ver con el problema. A medida que el tamaño de un 86.248 +proyecto---y el tiempo que toma ensamblarlo y probarlo---crece, usted 86.249 +se acerca rápidamente a un límite con este enfoque ``pruebe antes de 86.250 +comprar'', en el que tiene más conjuntos de cambios a probar que 86.251 +tiempo para ocuparse de ellos. El resultado inevitable es frustración 86.252 +para todos los que estén involucrados. 86.253 + 86.254 +Una aproximación que permite manejar mejor el crecimiento es hacer que 86.255 +la gente ensamble y pruebe antes de empujar, y ejecutar el ensamble y 86.256 +pruebas automáticas centralmente \emph{después} de empujar, para 86.257 +asegurarse de que todo esté bien. La ventaja de este enfoque es que no 86.258 +impone un límite a la rata en la que un repositorio puede aceptar 86.259 +cambios. 86.260 + 86.261 +\section{Tutorial corto de uso de ganchos} 86.262 +\label{sec:hook:simple} 86.263 + 86.264 +Escribir un gancho para Mercurial es fácil. Empecemos con un gancho 86.265 +que se ejecute cuando usted termine un \hgcmd{commit}, y simplemente 86.266 +muestre el hash del conjunto de cambios que usted acaba de crear. El 86.267 +gancho se llamará \hook{commit}. 86.268 + 86.269 +\begin{figure}[ht] 86.270 + \interaction{hook.simple.init} 86.271 + \caption{Un gancho simple que se ejecuta al hacer la consignación de 86.272 + un conjunto de cambios} 86.273 + \label{ex:hook:init} 86.274 +\end{figure} 86.275 + 86.276 +Todos los ganchos siguen el patrón del ejemplo~\ref{ex:hook:init}. 86.277 +Usted puede añadir una entrada a la sección \rcsection{hooks} de su 86.278 +fichero \hgrc. A la izquierda está el nombre del evento respecto al 86.279 +cual dispararse; a la derecha está la acción a llevar a cabo. Como 86.280 +puede ver, es posible ejecutar cualquier orden de la línea de comandos 86.281 +en un gancho. Mercurial le pasa información extra al gancho usando 86.282 +variables de entorno (busque \envar{HG\_NODE} en el ejemplo). 86.283 + 86.284 +\subsection{Llevar a cabo varias acciones por evento} 86.285 + 86.286 +A menudo, usted querrá definir más de un gancho para un tipo de evento 86.287 +particular, como se muestra en el ejemplo~\ref{ex:hook:ext}. 86.288 +Mercurial le permite hacer esto añadiendo una \emph{extensión} al 86.289 +final del nombre de un gancho. Usted extiende el nombre del gancho 86.290 +%TODO Yuk, no me gusta ese "parada completa" 86.291 +poniendo el nombre del gancho, seguido por una parada completa (el 86.292 +caracter ``\texttt{.}''), seguido de algo más de texto de su elección. 86.293 +Por ejemplo, Mercurial ejecutará tanto \texttt{commit.foo} como 86.294 +\texttt{commit.bar} cuando ocurra el evento \texttt{commit}. 86.295 + 86.296 +\begin{figure}[ht] 86.297 + \interaction{hook.simple.ext} 86.298 + \caption{Definición de un segundo gancho \hook{commit}} 86.299 + \label{ex:hook:ext} 86.300 +\end{figure} 86.301 + 86.302 +Para dar un orden bien definido de ejecución cuando hay múltiples 86.303 +ganchos definidos para un evento, Mercurial ordena los ganchos de 86.304 +acuerdo a su extensión, y los ejecuta en dicho orden. En el ejemplo de 86.305 +arribam \texttt{commit.bar} se ejecutará antes que 86.306 +\texttt{commit.foo}, y \texttt{commit} se ejecutará antes de ambos. 86.307 + 86.308 +Es una buena idea usar una extensión descriptiva cuando usted define 86.309 +un gancho. Esto le ayudará a recordar para qué se usa el gancho. Si el 86.310 +gancho falla, usted recibirá un mensaje de error que contiene el 86.311 +nombre y la extensión del gancho, así que usar una extensión 86.312 +descriptiva le dará una pista inmediata de porqué el gancho falló (vea 86.313 +un ejemplo en la sección~\ref{sec:hook:perm}). 86.314 + 86.315 +\subsection{Controlar cuándo puede llevarse a cabo una actividad} 86.316 +\label{sec:hook:perm} 86.317 + 86.318 +En los ejemplos anteriores, usamos el gancho \hook{commit}, que es 86.319 +ejecutado después de que se ha completado una consignación. Este es 86.320 +uno de los varios ganchos que Mercurial ejecuta luego de que una 86.321 +actividad termina. Tales ganchos no tienen forma de influenciar la 86.322 +actividad como tal. 86.323 + 86.324 +Mercurial define un número de eventos que ocurren antes de que una 86.325 +actividad empiece; o luego de que empiece, pero antes de que termine. 86.326 +Los ganchos que se disparan con estos eventos tienen la capacidad 86.327 +adicional de elegir si la actividad puede continuar, o si su ejecución 86.328 +es abortada. 86.329 + 86.330 +El gancho \hook{pretxncommit} se ejecuta justo antes de que una 86.331 +consignación se ejecute. En otras palabras, los metadatos que 86.332 +representan el conjunto de cambios han sido escritos al disco, pero no 86.333 +se ha terminado la transacción. El gancho \hook{pretxncommit} tiene la 86.334 +capacidad de decidir si una transacción se completa, o debe 86.335 +deshacerse. 86.336 + 86.337 +Si el gancho \hook{pretxncommit} termina con un código de salida de 86.338 +cero, se permite que la transacción se complete; la consignación 86.339 +termina; y el gancho \hook{commit} es ejecutado. Si el gancho 86.340 +\hook{pretxncommit} termina con un código de salida diferente de cero, 86.341 +la transacción es revertida; los metadatos representando el conjunto 86.342 +de cambios son borrados; y el gancho \hook{commit} no es ejecutado. 86.343 + 86.344 +\begin{figure}[ht] 86.345 + \interaction{hook.simple.pretxncommit} 86.346 + \caption{Uso del gancho \hook{pretxncommit} para controlar consignaciones} 86.347 + \label{ex:hook:pretxncommit} 86.348 +\end{figure} 86.349 + 86.350 +El gancho en el ejemplo~\ref{ex:hook:pretxncommit} revisa si el 86.351 +mensaje de consignación contiene el ID de algún fallo. Si lo contiene, 86.352 +la consignación puede continuar. Si no, la consignación es cancelada. 86.353 + 86.354 +\section{Escribir sus propios ganchos} 86.355 + 86.356 +Cuando usted escriba un gancho, puede encontrar útil el ejecutar 86.357 +Mercurial o bien pasándole la opción \hggopt{-v}, o con el valor de 86.358 +configuración \rcitem{ui}{verbose} fijado en ``true'' (verdadero). 86.359 +Cuando lo haga, Mercurial imprimirá un mensaje antes de llamar cada 86.360 +gancho. 86.361 + 86.362 +\subsection{Escoger cómo debe ejecutarse su gancho} 86.363 +\label{sec:hook:lang} 86.364 + 86.365 +Usted puede escribir un gancho que funcione como un programa normal 86.366 +---típicamente un guión de línea de comandos---o como una función de 86.367 +Python que se ejecuta dentro del proceso Mercurial. 86.368 + 86.369 +Escribir un gancho como un programa externo tiene la ventaja de que no 86.370 +requiere ningún conocimiento del funcionamiento interno de Mercurial. 86.371 +Usted puede ejecutar comandos Mercurial normales para obtener la 86.372 +informción extra que pueda necesitar. La contraparte de esto es que 86.373 +los ganchos externos son más lentos que los ganchos internos 86.374 +ejecutados dentro del proceso. 86.375 + 86.376 +Un gancho Python interno tiene acceso completo a la API de Mercurial, 86.377 +y no se ``externaliza'' a otro proceso, así que es inherentemente más 86.378 +rápido que un gancho externo. Adicionalmente es más fácil obtener la 86.379 +mayoría de la información que un gancho requiere a través de llamadas 86.380 +directas a la API de Mercurial que hacerlo ejecutando comandos 86.381 +Mercurial. 86.382 + 86.383 +Si se siente a gusto con Python, o requiere un alto desempeño, 86.384 +escribir sus ganchos en Python puede ser una buena elección. Sin 86.385 +embargo, cuando usted tiene un gancho bastante directo por escribir y 86.386 +no le importa el desempeño (el caso de la mayoría de los ganchos), es 86.387 +perfectamente admisible un guión de línea de comandos. 86.388 + 86.389 +\subsection{Parámetros para ganchos} 86.390 +\label{sec:hook:param} 86.391 + 86.392 +Mercurial llama cada gancho con un conjunto de paŕametros bien 86.393 +definidos. En Python, un parámetro se pasa como argumento de palabra 86.394 +clave a su función de gancho. Para un programa externo, los parámetros 86.395 +son pasados como variables de entornos. 86.396 + 86.397 +Sin importar si su gancho está escrito en Python o como guión de línea 86.398 +de comandos, los nombres y valores de los parámetros específicos de 86.399 +los ganchos serán los mismos. Un parámetro booleano será representado 86.400 +como un valor booleano en Python, pero como el número 1 (para 86.401 +``verdadero'') o 0 (para falso) en una variable de entorno para un 86.402 +gancho externo. Si un parámetro se llama \texttt{foo}, el argumento de 86.403 +palabra clave para un gancho en Python también se llamará 86.404 +\texttt{foo}, mientras que la variable de entorno para un gancho 86.405 +externo se llamará \texttt{HG\_FOO}. 86.406 + 86.407 +\subsection{Valores de retorno de ganchos y control de actividades} 86.408 + 86.409 +Un gancho que se ejecuta exitosamente debe terminar con un código de 86.410 +salida de cero, si es externo, o retornar el valor booleano 86.411 +``falso'', si es interno. Un fallo se indica con un código de salida 86.412 +diferente de cero desde un gancho externo, o un valor de retorno 86.413 +booleano ``verdadero''. Si un gancho interno genera una excepción, se 86.414 +considera que el gancho ha fallado. 86.415 + 86.416 +Para los ganchos que controlan si una actividad puede continuar o no, 86.417 +cero/falso quiere decir ``permitir'', mientras que 86.418 +% TODO me suena mejor "no permitir" que "denegar" 86.419 +no-cero/verdadero/excepción quiere decir ``no permitir''. 86.420 + 86.421 +\subsection{Escribir un gancho externo} 86.422 + 86.423 +Cuando usted define un gancho externo en su fichero \hgrc\ y el mismo 86.424 +es ejecutado, dicha definición pasa a su intérprete de comandos, que 86.425 +hace la interpretación correspondiente. Esto significa que usted puede 86.426 +usar elementos normales del intérprete en el cuerpo del gancho. 86.427 + 86.428 +Un gancho ejecutable siempre es ejecutado con su directorio actual 86.429 +fijado al directorio raíz del repositorio. 86.430 + 86.431 +Cada parámetro para el gancho es pasado como una variable de entorno; 86.432 +el nombre está en mayúsculas, y tiene como prefijo la cadena 86.433 +``\texttt{HG\_}''. 86.434 + 86.435 +Con la excepción de los parámetros para los ganchos, Mercurial no 86.436 +define o modifica ninguna variable de entorno al ejecutar un gancho. 86.437 +Es útil recordar esto al escribir un gancho global que podría ser 86.438 +ejecutado por varios usuarios con distintas variables de entorno 86.439 +fijadas. En situaciones con múltiples usuarios, usted no debería 86.440 +asumir la existencia de ninguna variable de entorno, ni que sus 86.441 +valores sean los mismos que tenían cuando usted probó el gancho en su 86.442 +ambiente de trabajo. 86.443 + 86.444 +\subsection{Indicar a Mercurial que use un gancho interno} 86.445 + 86.446 +La sintaxis para definir un gancho interno en el fichero \hgrc\ es 86.447 +ligeramente diferente de la usada para un gancho externo. El valor del 86.448 +gancho debe comenzar con el texto ``\texttt{python:}'', y continuar 86.449 +con el nombre completamente cualificado de un objeto invocable que se 86.450 +usará como el valor del gancho. 86.451 + 86.452 +El módulo en que vive un gancho es importado automáticamente cuando se 86.453 +ejecuta un gancho. Siempre que usted tenga el nombre del módulo y la 86.454 +variable de entorno \envar{PYTHONPATH} ajustada adecuadamente, todo 86.455 +debería funcionar sin problemas. 86.456 + 86.457 +El siguiente fragmento de ejemplo de un fichero \hgrc\ ilustra la 86.458 +sintaxis y significado de los conceptos que acabamos de describir. 86.459 +\begin{codesample2} 86.460 + [hooks] 86.461 + commit.example = python:mymodule.submodule.myhook 86.462 +\end{codesample2} 86.463 +Cuando Mercurial ejecuta el gancho \texttt{commit.example}, importa 86.464 +\texttt{mymodule.submodule}, busca el objeto invocable llamado 86.465 +\texttt{myhook}, y lo invoca (llama). 86.466 + 86.467 +\subsection{Escribir un gancho interno} 86.468 + 86.469 +El gancho interno más sencillo no hace nada, pero ilustra la 86.470 +estructura básica de la API\ndt{\emph{Application Progamming 86.471 +Interface}, Interfaz para Programación de Aplicaciones} para ganchos: 86.472 +\begin{codesample2} 86.473 + def myhook(ui, repo, **kwargs): 86.474 + pass 86.475 +\end{codesample2} 86.476 +El primer argumento para un gancho Python siempre es un objeto 86.477 +\pymodclass{mercurial.ui}{ui}. El segundo es un objeto repositorio; 86.478 +de momento, siempre es una instancia de 86.479 +\pymodclass{mercurial.localrepo}{localrepository}. Después de estos 86.480 +dos argumentos están los argumentos de palabra clave. Los argumentos 86.481 +que se pasen dependerán del tipo de gancho que se esté llamando, pero 86.482 +un gancho siempre puede ignorar los argumentos que no le interesen, 86.483 +relegándolos a un diccionario de argumentos por palabras clave, como se 86.484 +hizo arriba con \texttt{**kwargs}. 86.485 + 86.486 +\section{Ejemplos de ganchos} 86.487 + 86.488 +\subsection{Escribir mensajes de consignación significativos} 86.489 + 86.490 +Es difícil de imaginar un mensaje de consignación útil y al mismo 86.491 +tiempo muy corto. El simple gancho \hook{pretxncommit} de la 86.492 +figura~\ref{ex:hook:msglen.go} evitará que usted consigne un conjunto 86.493 +de cambios con un mensaje de menos de 10 bytes de longitud. 86.494 + 86.495 +\begin{figure}[ht] 86.496 + \interaction{hook.msglen.go} 86.497 + \caption{Un gancho que prohíbe mensajes de consignación demasiado 86.498 + cortos} 86.499 + \label{ex:hook:msglen.go} 86.500 +\end{figure} 86.501 + 86.502 +\subsection{Comprobar espacios en blanco finales} 86.503 + 86.504 +Un uso interesante para ganchos relacionados con consignaciones es 86.505 +ayudarle a escribir código más limpio. Un ejemplo simple de 86.506 +%TODO dictum => regla 86.507 +``código más limpio'' es la regla de que un cambio no debe añadir 86.508 +líneas de texto que contengan ``espacios en blanco finales''. El 86.509 +espacio en blanco final es una serie de caracteres de espacio y 86.510 +tabulación que se encuentran al final de una línea de texto. En la 86.511 +mayoría de los casos, el espacio en blanco final es innecesario, ruido 86.512 +invisible, pero ocasionalmente es problemático, y la gente en general 86.513 +prefiere deshacerse de él. 86.514 + 86.515 +Usted puede usar cualquiera de los ganchos \hook{precommit} o 86.516 +\hook{pretxncommit} para revisar si tiene el problema de los espacios 86.517 +en blanco finales. Si usa el gancho \hook{precommit}, el gancho no 86.518 +sabrá qué ficheros se están consignando, por lo que se tendrá que 86.519 +revisar cada fichero modificado en el repositorio para ver si tiene 86.520 +espacios en blanco finales. Si usted sólo quiere consignar un cambio 86.521 +al fichero \filename{foo}, y el fichero \filename{bar} contiene 86.522 +espacios en blanco finales, hacer la revisión en el gancho 86.523 +\hook{precommit} evitará que usted haga la consignación de 86.524 +\filename{foo} debido al problem en \filename{bar}. Este no parece el 86.525 +enfoque adeucado. 86.526 + 86.527 +Si usted escogiera el gancho \hook{pretxncommit}, la revisión no 86.528 +ocurriría sino hasta justo antes de que la transacción para la 86.529 +consignación se complete. Esto le permitirá comprobar por posibles 86.530 +problemas sólo en los ficheros que serán consignados. Sin embargo, si 86.531 +usted ingresó el mensaje de consignación de manera interactiva y el 86.532 +%TODO roll-back 86.533 +gancho falla, la transacción será deshecha; usted tendrá que 86.534 +reingresar el mensaje de consignación luego de que corrija el problema 86.535 +con los espacios en blanco finales y ejecute \hgcmd{commit} de nuevo. 86.536 + 86.537 +\begin{figure}[ht] 86.538 + \interaction{hook.ws.simple} 86.539 + \caption{Un gancho simple que revisa si hay espacios en blanco 86.540 + finales} 86.541 + \label{ex:hook:ws.simple} 86.542 +\end{figure} 86.543 + 86.544 +La figura~\ref{ex:hook:ws.simple} presenta un gancho 86.545 +\hook{pretxncommit} simple que comprueba la existencia de espacios en 86.546 +blanco finales. Este gancho es corto, pero no brinda mucha ayuda. 86.547 +Termina con un código de salida de error si un cambio añade una línea 86.548 +con espacio en blanco final a cualquier fichero, pero no muestra 86.549 +ninguna información que pueda ser útil para identificar el fichero o 86.550 +la línea de texto origen del problema. También tiene la agradable 86.551 +propiedad de no prestar atención a las líneas que no sufrieron 86.552 +modificaciones; sólo las líneas que introducen nuevos espacios en 86.553 +blanco finales causan problemas. 86.554 + 86.555 +\begin{figure}[ht] 86.556 + \interaction{hook.ws.better} 86.557 + \caption{Un mejor gancho para espacios en blanco finales} 86.558 + \label{ex:hook:ws.better} 86.559 +\end{figure} 86.560 + 86.561 +El ejemplo de la figura~\ref{ex:hook:ws.better} es mucho más complejo, 86.562 +pero también más útil. El gancho procesa un diff unificado para 86.563 +revisar si alguna línea añade espacios en blanco finales, e imprime el 86.564 +nombre del fichero y el número de línea de cada ocurrencia. Aún mejor, 86.565 +si el cambio añade espacios en blanco finales, este gancho guarda el 86.566 +mensaje de consignación e imprime el nombre del fichero en el que el 86.567 +mensaje fue guardado, antes de terminar e indicarle a Mercurial que 86.568 +deshaga la transacción, para que uste pueda usar 86.569 +\hgcmdargs{commit}{\hgopt{commit}{-l}~\emph{nombre\_fichero}} para 86.570 +reutilizar el mensaje de consignación guardado anteriormente, una vez 86.571 +usted haya corregido el problema. 86.572 + 86.573 +Como anotación final, note en la figura~\ref{ex:hook:ws.better} el 86.574 +%TODO on-site => in-situ ? 86.575 +uso de la característica de edición \emph{in-situ} de \command{perl} 86.576 +para eliminar los espacios en blanco finales en un fichero. Esto es 86.577 +lo suficientemente conciso y poderoso para que lo presente aquí. 86.578 +% TODO corregí el backslash, y comprobé por mi cuenta un archivo 86.579 +% aparte, y el comando hace lo que debe hacer. Favor copiar del pdf el 86.580 +% comando perl y comprobar con un archivo con espacios en blanco 86.581 +% finales, y si todo está bien (que debería), borrar esta nota 86.582 +\begin{codesample2} 86.583 + perl -pi -e 's,\textbackslash{}s+\$,,' nombre\_fichero 86.584 +\end{codesample2} 86.585 + 86.586 +\section{Ganchos adicionales} 86.587 + 86.588 +Mercurial se instala con varios ganchos adicionales. Usted puede 86.589 +encontrarlos en el directorio \dirname{hgext} del árbol de ficheros 86.590 +fuente de Mercurial. Si usted está usando un paquete binario de 86.591 +Mercurial, los ganchos estarán ubicados en el directorio 86.592 +\dirname{hgext} en donde su instalador de paquetes haya puesto a 86.593 +Mercurial. 86.594 + 86.595 +\subsection{\hgext{acl}---control de acceso a partes de un repositorio} 86.596 + 86.597 +La extensión \hgext{acl} le permite controlar a qué usuarios remotos 86.598 +les está permitido empujar conjuntos de cambios a un servidor en red. 86.599 +Usted puede proteger cualquier porción de un repositorio (incluyendo 86.600 +el repositorio completo), de tal manera que un usuario remoto 86.601 +específico pueda empujar cambios que no afecten la porción protegida. 86.602 + 86.603 +Esta extensión implementa control de acceso basado en la identidad del 86.604 +usuario que empuja los conjuntos de cambios, \emph{no} en la identidad 86.605 +de quien hizo la consignación de los mismos. Usar este gancho tiene 86.606 +sentido sólo si se tiene un servidor adecuadamente asegurado que 86.607 +autentique a los usuarios remotos, y si usted desea segurarse de que 86.608 +sólo se le permita a ciertos usuarios empujar cambios a dicho 86.609 +servidor. 86.610 + 86.611 +\subsubsection{Configuración del gancho \hook{acl}} 86.612 + 86.613 +Para administrar los conjuntos de cambios entrantes, se debe usar el 86.614 +gancho \hgext{acl} como un gancho de tipo \hook{pretxnchangegroup}. 86.615 +Esto le permite ver qué ficheros son modificados por cada conjunto de 86.616 +%TODO rollback => "deshacer el efecto" 86.617 +cambios entrante, y deshacer el efecto de un grupo de conjuntos de 86.618 +cambios si alguno de ellos modifica algún fichero ``prohibido''. 86.619 +Ejemplo: 86.620 +\begin{codesample2} 86.621 + [hooks] 86.622 + pretxnchangegroup.acl = python:hgext.acl.hook 86.623 +\end{codesample2} 86.624 + 86.625 +La extensión \hgext{acl} es configurada mediante tres secciones. 86.626 + 86.627 +La sección \rcsection{acl} sólo tiene una entrada, 86.628 +\rcitem{acl}{sources}\ndt{Fuentes.}, que lista las fuentes de los 86.629 +conjuntos de cambios entrantes a las que el gancho debe prestar 86.630 +atención. Usualmente usted no necesita configurar esta sección. 86.631 +\begin{itemize} 86.632 + \item[\rcitem{acl}{serve}] Controlar conjuntos de 86.633 + cambios entrantes que están llegando desde un repositorio a 86.634 + través de http o ssh. Este es el valor por defecto de 86.635 + \rcitem{acl}{sources}, y usualmente es el único valor de 86.636 + configuración que necesitará para este ítem. 86.637 +\item[\rcitem{acl}{pull}] Controlar conjuntos de cambios entrantes que 86.638 + lleguen vía un pull (jalado) desde un repositorio local. 86.639 +\item[\rcitem{acl}{push}] Controlar conjuntos de cambios entrantes que 86.640 + lleguen vía un push (empuje) desde un repositorio local. 86.641 +\item[\rcitem{acl}{bundle}] Controlar conjuntos de cambios entrantes 86.642 + %TODO bundle 86.643 + que lleguen desde otro repositorio a través de un paquete. 86.644 +\end{itemize} 86.645 + 86.646 +La sección \rcsection{acl.allow} controla los usuarios a los que les 86.647 +está permitido añadir conjuntos de cambios al repositorio. Si esta 86.648 +sección no está presente, se le permite acceso a todos los usuarios 86.649 +excepto a los que se les haya negado explícitamente el acceso. Si 86.650 +esta sección no está presente, se niega el acceso a todos los usuarios 86.651 +excepto a todos a los que se les haya permitido de manera explícita 86.652 +(así que una sección vacía implica que se niega el acceso a todos los 86.653 +usuarios). 86.654 + 86.655 +La sección \rcsection{acl.deny} determina a qué usuarios no se les 86.656 +permite añadir conjuntos de cambios al repositorio. Si esta sección no 86.657 +está presente o está vacía, no se niega el acceso a ningún usuario. 86.658 + 86.659 +La sintaxis para los ficheros \rcsection{acl.allow} y 86.660 +\rcsection{acl.deny} es idéntica. A la izquierda de cada entrada se 86.661 +encuentra un patrón glob que asocia ficheros o directorios, respecto a 86.662 +la raíz del repositorio; a la derecha, un nombre usuario. 86.663 + 86.664 +En el siguiente ejemplo, el usuario \texttt{escritordoc} sólo puede 86.665 +empujar cambios al directorio \dirname{docs} del repositorio, mientras 86.666 +que \texttt{practicante} puede enviar cambios a cualquier fichero o 86.667 +directorio excepto \dirname{fuentes/sensitivo}. 86.668 +\begin{codesample2} 86.669 + [acl.allow] 86.670 + docs/** = escritordoc 86.671 + 86.672 + [acl.deny] 86.673 + fuentes/sensitivo/** = practicante 86.674 +\end{codesample2} 86.675 + 86.676 +\subsubsection{Pruebas y resolución de problemas} 86.677 + 86.678 +Si usted desea probar el gancho \hgext{acl}, ejecútelo habilitando la 86.679 +opción de salida de depuración habilitada. Ya que usted probablemente 86.680 +lo estará ejecutando en un servidor donde no es conveniente (o incluso 86.681 +posible) pasar la opción \hggopt{--debug}, no olvide que usted puede 86.682 +habilitar la salida de depuración en su \hgrc: 86.683 +\begin{codesample2} 86.684 + [ui] 86.685 + debug = true 86.686 +\end{codesample2} 86.687 +Con esto habilitado, el gancho \hgext{acl} imprimirá suficiente 86.688 +información para permitirle saber porqué está permitiendo o denegando 86.689 +la operación de empujar a usuarios específicos. 86.690 + 86.691 +\subsection{\hgext{bugzilla}---integración con Bugzilla} 86.692 + 86.693 +La extensión \hgext{bugzilla} añade un comentario a un fallo Bugzilla 86.694 +siempre que encuentre una referencia al ID de dicho fallo en un 86.695 +mensaje de consignación. Usted puede instalar este gancho en un 86.696 +servidor compartido, para que cada vez que un usuario remoto empuje 86.697 +cambios al servidor, el gancho sea ejecutado. 86.698 + 86.699 +Se añade un comentario al fallo que se ve así (usted puede configurar 86.700 +los contenidos del comentario---vea más abajo): 86.701 +%TODO traducir? 86.702 +\begin{codesample2} 86.703 + Changeset aad8b264143a, made by Joe User <joe.user@domain.com> in 86.704 + the frobnitz repository, refers to this bug. 86.705 + 86.706 + For complete details, see 86.707 + http://hg.domain.com/frobnitz?cmd=changeset;node=aad8b264143a 86.708 + 86.709 + Changeset description: 86.710 + Fix bug 10483 by guarding against some NULL pointers 86.711 +\end{codesample2} 86.712 +El valor de este gancho se encuentra en que automatiza el proceso de 86.713 +actualizar un fallo cuando un conjunto de cambios se refiera a él. Si 86.714 +usted configura este gancho adecuadamente, hará fácil para la gente 86.715 +navegar directamente desde un fallo Bugzilla a un conjunto de cambios 86.716 +que se refiere a ese fallo. 86.717 + 86.718 +Usted puede usar el código de este gancho como un punto de partida 86.719 +para otras recetas de integración con Bugzilla aún más exóticas. Acá 86.720 +hay algunas posibilidades: 86.721 +\begin{itemize} 86.722 +\item Requerir que cada conjunto de cambios tenga un ID de fallo en su 86.723 + mensaje de consignación. En este caso, usted querrá configurar el 86.724 + gancho como uno de tipo \hook{pretxncommit}. Esto le permitirá al 86.725 + gancho rechazar cambios que no contiene IDs de fallos. 86.726 +\item Permitir a los conjuntos de cambios entrantes modificar 86.727 + automáticamente el \emph{estado} de un fallo, así como simplemente 86.728 + añadir un comentario. Por ejemplo, el gancho podría reconocer la 86.729 + cadena ``corregido fallo 31337'' como la señal de que debería 86.730 + actualizar el estado del fallo 31337 a ``requiere pruebas''. 86.731 +\end{itemize} 86.732 + 86.733 +\subsubsection{Configuración del gancho \hook{bugzilla}} 86.734 +\label{sec:hook:bugzilla:config} 86.735 + 86.736 +Usted debería configurar este gancho en el \hgrc\ de su servidor como 86.737 +un gancho \hook{incoming}\ndt{Entrante.}, por ejemplo como sigue: 86.738 +\begin{codesample2} 86.739 + [hooks] 86.740 + incoming.bugzilla = python:hgext.bugzilla.hook 86.741 +\end{codesample2} 86.742 + 86.743 +Debido a la naturaleza especializada de este gancho, y porque Bugzilla 86.744 +no fue escrito con este tipo de integración en mente, configurar este 86.745 +% TODO involved => complejo ? no intarwebs here :( 86.746 +gancho es un proceso algo complejo. 86.747 + 86.748 +Antes de empezar, usted debe instalar la interfaz de Python para MySQL 86.749 +en los sistemas en los que se vaya a ejecutar el gancho. Si no está 86.750 +disponible como paquete binario para su sistema, usted puede descargar 86.751 +el paquete desde~\cite{web:mysql-python}. 86.752 + 86.753 +La información para configurar este gancho se ubica en la sección 86.754 +\rcsection{bugzilla} de su \hgrc. 86.755 +\begin{itemize} 86.756 +\item[\rcitem{bugzilla}{version}] La versión de Bugzilla instalada en 86.757 + el servidor. El esquema de base de datos que Bugzilla usa cambia 86.758 + ocasionalmente, así que este gancho debe saber exactamente qué 86.759 + esquema usar. A la fecha, la única versión soportada es la 86.760 + \texttt{2.16}. 86.761 +\item[\rcitem{bugzilla}{host}] El nombre de máquina (\emph{hostname}) 86.762 + del servidor MySQL que almacena sus datos Bugzilla. La base de datos 86.763 + debe ser configurada para permitir conexiones desde las máquinas en 86.764 + las que usted ejecute el gancho \hook{bugzilla}. 86.765 +\item[\rcitem{bugzilla}{user}] El nombre de usuario que se usará para 86.766 + conectarse al servidor MySQL. La base de datos debe ser configurada 86.767 + para permitir a dicho usuario conectarse desde cualquiera de las 86.768 + máquinas en las que se ejecute el gancho \hook{bugzilla}. Este 86.769 + usuario debe tener acceso y poder modificar las tablas de Bugzilla. 86.770 + El valor por defecto para este ítem es \texttt{bugs}, que es el 86.771 + nombre estándar del usuario para Bugzilla en una base de datos 86.772 + MySQL. 86.773 +\item[\rcitem{bugzilla}{password}] La contraseña MySQL para el usuario 86.774 + configurado anteriormente. Ésta es almacenada como texto plano, así 86.775 + que usted deberá asegurarse de que los usuarios no autorizados no 86.776 + puedan leer el fichero \hgrc\ en donde usted guarda esta 86.777 + información. 86.778 +\item[\rcitem{bugzilla}{db}] El nombre de la base de datos Bugzilla en 86.779 + el servidor MySQL. El nombre por defecto para este ítem es 86.780 + \texttt{bugs}, que es el nombre estándar de la base de datos MySQL 86.781 + en donde Bugzilla almacena sus datos. 86.782 +\item[\rcitem{bugzilla}{notify}] Si usted desea que Bugzilla envíe un 86.783 + %TODO suBscriptores? 86.784 + correo de notificación a los suscriptores después de que el gancho 86.785 + haya añadido un comentario a un fallo, necesitará que este gancho 86.786 + ejecute un comando siempre que actualice la base de datos. El 86.787 + comando que se ejecute depende de en dónde haya sido instalado 86.788 + Bugzilla, pero típicamente se verá así, si usted ha instalado 86.789 + Bugzilla en \dirname{/var/www/html/bugzilla}: 86.790 + \begin{codesample4} 86.791 + cd /var/www/html/bugzilla && ./processmail %s nobody@nowhere.com 86.792 + \end{codesample4} 86.793 + El programa \texttt{processmail} de Bugzilla espera recibir un ID de 86.794 + fallo (el gancho reemplaza ``\texttt{\%s}'' por el ID del fallo) y 86.795 + una dirección de correo. También espera poder escribir a ciertos 86.796 + ficheros en el directorio en que se ejecuta. Si Bugzilla y éste 86.797 + gancho no están instalados en la misma máquina, usted deberá 86.798 + encontrar una manera de ejecutar \texttt{processmail} en el servidor 86.799 + donde está instalado Bugzilla. 86.800 +\end{itemize} 86.801 + 86.802 +\subsubsection{Asociar nombres de consignadores a nombres de usuario 86.803 +Bugzilla} 86.804 + 86.805 +Por defecto, el gancho \hgext{bugzilla} trata de usar la dirección de 86.806 +correo electrónico de la persona que hizo la consignación del conjunto 86.807 +de cambios como el nombre de usuario Bugzilla con el cual debe 86.808 +actualizar el fallo. Si esto no se ajusta a sus necesidades, es 86.809 +posible asociar direcciones de correo a nombres de usuario Bugzilla 86.810 +usando una sección \rcsection{usermap}. 86.811 + 86.812 +Cada ítem en la sección \rcsection{usermap} contiene una dirección de 86.813 +correo electrónico a la izquierda, y un nombre de usuario Bugzilla a 86.814 +la derecha. 86.815 +\begin{codesample2} 86.816 + [usermap] 86.817 + jane.user@example.com = jane 86.818 +\end{codesample2} 86.819 +Usted puede mantener los datos de \rcsection{usermap} en un fichero 86.820 +\hgrc, o decirle al gancho \hgext{bugzilla} que lea la información 86.821 +desde un fichero \filename{usermap} externo. En este caso, usted 86.822 +puede almacenar los datos de \filename{usermap} en (por ejemplo) un 86.823 +repositorio modificable por los usuarios. Esto hace posible para sus 86.824 +usuarios mantener sus propias entradas \rcitem{bugzilla}{usermap}. El 86.825 +fichero \hgrc\ principal se vería así: 86.826 +\begin{codesample2} 86.827 + # fichero hgrc normal se refiere a un fichero usermap externo 86.828 + [bugzilla] 86.829 + usermap = /home/hg/repos/userdata/bugzilla-usermap.conf 86.830 +\end{codesample2} 86.831 +Mientras que el fichero \filename{usermap} al que se hace referencia 86.832 +se vería así: 86.833 +\begin{codesample2} 86.834 + # bugzilla-usermap.conf - dentro de un repositorio hg 86.835 + [usermap] 86.836 + stephanie@example.com = steph 86.837 +\end{codesample2} 86.838 + 86.839 +\subsubsection{Configurar el texto que se añade a un fallo} 86.840 + 86.841 +Usted puede configurar el texto que este gancho añade como comentario; 86.842 +usted los especifica como una plantilla Mercurial. Varias entradas 86.843 +\hgrc\ (aún en la sección \rcsection{bugzilla}) controlan este 86.844 +comportamiento. 86.845 +\begin{itemize} 86.846 +\item[\texttt{strip}] La cantidad de elementos iniciales de ruta a 86.847 + remover de un nombre de ruta del repositorio para construir una ruta 86.848 + parcial para una URL. Por ejemplo, si los repositorios en su 86.849 + servidor se ubican en \dirname{/home/hg/repos}, y usted tiene un 86.850 + repositorio cuya ruta es \dirname{/home/hg/repos/app/tests}, 86.851 + entonces fijar \texttt{strip} a \texttt{4} resultará en una ruta 86.852 + parcial de \dirname{app/tests}. El gancho hará disponible esta ruta 86.853 + parcial cuando expanda una plantilla, como \texttt{webroot}. 86.854 +\item[\texttt{template}] El texto de la plantilla a usar. En adición a 86.855 + las variables usuales relacionadas con conjuntos de cambios, esta 86.856 + plantilla puede usar \texttt{hgweb} (el valor del ítem de 86.857 + configuración \texttt{hgweb} de arriba) y \texttt{webroot} (la ruta 86.858 + construida usando \texttt{strip} arriba). 86.859 +\end{itemize} 86.860 + 86.861 +Adicionalmente, usted puede añadir un ítem \rcitem{web}{baseurl} a la 86.862 +sección \rcsection{web} de su \hgrc. El gancho \hgext{bugzilla} 86.863 +publicará esto cuando expanda una plantilla, como la cadena base a 86.864 +usar cuando se construya una URL que le permita a los usuarios navegar 86.865 +desde un comentario de Bugzilla a la vista de un conjunto de cambios. 86.866 +Ejemplo: 86.867 +\begin{codesample2} 86.868 + [web] 86.869 + baseurl = http://hg.domain.com/ 86.870 +\end{codesample2} 86.871 + 86.872 +A continuación se presenta un ejemplo completo de configuración para 86.873 +el gancho \hgext{bugzilla}. 86.874 +%TODO traducir? 86.875 +\begin{codesample2} 86.876 + [bugzilla] 86.877 + host = bugzilla.example.com 86.878 + password = mypassword 86.879 + version = 2.16 86.880 + # server-side repos live in /home/hg/repos, so strip 4 leading 86.881 + # separators 86.882 + strip = 4 86.883 + hgweb = http://hg.example.com/ 86.884 + usermap = /home/hg/repos/notify/bugzilla.conf 86.885 + template = Changeset \{node|short\}, made by \{author\} in the \{webroot\} 86.886 + repo, refers to this bug.\\nFor complete details, see 86.887 + \{hgweb\}\{webroot\}?cmd=changeset;node=\{node|short\}\\nChangeset 86.888 + description:\\n\\t\{desc|tabindent\} 86.889 +\end{codesample2} 86.890 + 86.891 +\subsubsection{Pruebas y resolución de problemas} 86.892 + 86.893 +Los problemas más comunes que aparecen en la configuración del gancho 86.894 +\hgext{bugzilla} suelen estar relacionados con la ejecución del guión 86.895 +de Bugzilla \filename{processmail} y la asociación de nombres de 86.896 +consignadores a nombres de usuario. 86.897 + 86.898 +Recuerde que en la sección~\ref{sec:hook:bugzilla:config} arriba el 86.899 +usuario que ejecuta el proceso Mercurial en el servidor es también 86.900 +el usuario que ejecutará el guión \filename{processmail}. El guión 86.901 +\filename{processmail} algunas veces hace que Bugzilla escriba en 86.902 +ficheros en su directorio de configuración, y los ficheros de 86.903 +configuración de Bugzilla usualmente son propiedad del usuario bajo el 86.904 +cual se ejecuta el servidor web. 86.905 + 86.906 +Usted puede hacer que \filename{processmail} sea ejecutado con la 86.907 +identidad del usuario adecuado usando el comando \command{sudo}. A 86.908 +continuación se presenta una entrada de ejemplo para un fichero 86.909 +\filename{sudoers}. 86.910 +\begin{codesample2} 86.911 + hg_user = (httpd_user) NOPASSWD: /var/www/html/bugzilla/processmail-wrapper %s 86.912 +\end{codesample2} 86.913 +Esto permite que el usuario \texttt{hg\_user} ejecute el programa 86.914 +\filename{processmail-wrapper} con la identidad del usuario 86.915 +\texttt{httpd\_user}. 86.916 + 86.917 +Esta indirección a través de un guión envoltorio es necesaria, porque 86.918 +\filename{processmail} espera que al ser ejecutado su directorio 86.919 +actual sea aquel en el cual se instaló Bugzilla; usted no puede 86.920 +especificar ese tipo de condición en un fichero \filename{sudoers}. 86.921 +Los contenidos del giuón envoltorio son simples: 86.922 +\begin{codesample2} 86.923 + #!/bin/sh 86.924 + cd `dirname $0` && ./processmail "$1" nobody@example.com 86.925 +\end{codesample2} 86.926 +No parece importar qué dirección de correo se le pase a 86.927 +\filename{processmail}. 86.928 + 86.929 +Si su \rcsection{usermap} no es configurada correctamente, los 86.930 +usuarios verán un mensaje de error del gancho \hgext{bugzilla} cuando 86.931 +empujen cambios al servidor. El mensaje de error se verá así: 86.932 +\begin{codesample2} 86.933 + cannot find bugzilla user id for john.q.public@example.com 86.934 +\end{codesample2} 86.935 +Lo que esto quiere decir es que la dirección del consignador, 86.936 +\texttt{john.q.public@example.com}, no es un nombre de usuario 86.937 +Bugzilla válido, ni tiene una entrada en su \rcsection{usermap} que lo 86.938 +asocie con un nombre de usuario válido Bugzilla. 86.939 + 86.940 +\subsection{\hgext{notify}---enviar notificaciones de correo 86.941 +electrónico} 86.942 + 86.943 +%TODO feeds => notificaciones: lo más fácil es mirar en wikipedia 86.944 +Aunque el servidor web embebido de Mercurial provee notificaciones de 86.945 +cambios en cada repositorio, muchas personas prefieren recibir las 86.946 +notificaciones de cambios vía correo electrónico. El gancho 86.947 +\hgext{notify}\ndt{Notificación.} le permite a usted enviar 86.948 +notificaciones a un conjunto de direcciones de correo cuando lleguen 86.949 +conjuntos de cambios en los que los subscriptores estén interesados. 86.950 + 86.951 +De la misma forma que con el gancho \hgext{bugzilla}, el gancho 86.952 +\hgext{notify} está orientado a plantillas, así que usted puede 86.953 +personalizar los contenidos del mensaje de notificación que se envía. 86.954 + 86.955 +Por defecto, el gancho \hgext{notify} incluye un diff de cada conjunto 86.956 +%TODO que se envía? revisar, pienso que es ``que se recibe'' 86.957 +de cambios que se envía; usted puede limitar el tamaño del diff, o 86.958 +desactivar completamente esta característica. Es útil para permitir a 86.959 +los subscriptores revisar los cambios inmediatamente, en vez de tener 86.960 +que hacer clic para visitar una URL. 86.961 + 86.962 +\subsubsection{Configuración del gancho \hgext{notify}} 86.963 + 86.964 +Usted puede configurar el gancho \hgext{notify} para enviar un mensaje 86.965 +de correo por conjunto de cambios entrante, o uno por grupo entrante 86.966 +de conjuntos de cambios (todos los que llegaron en un único empuje o 86.967 +jalado). 86.968 +\begin{codesample2} 86.969 + [hooks] 86.970 + # enviar un correo por grupo de cambios 86.971 + changegroup.notify = python:hgext.notify.hook 86.972 + # enviar un correo por cambio 86.973 + incoming.notify = python:hgext.notify.hook 86.974 +\end{codesample2} 86.975 + 86.976 +La información para configurar este gancho se ubica en la sección 86.977 +\rcsection{notify} de un fichero \hgrc. 86.978 +\begin{itemize} 86.979 +\item[\rcitem{notify}{test}] Por defecto, este gancho no envía correos 86.980 + en absoluto; en vez de eso, imprime el mensaje que se 86.981 + \emph{enviaría}. Fije este ítem en \texttt{false} para permitir el 86.982 + envío de correos. El motivo por el que el envío de correos está 86.983 + desactivado es que hacen falta varios intentos para configurar esta 86.984 + extensión exactamente como usted desea, y sería maleducado enviar a 86.985 + los subscriptores una cantidad de notificaciones ``rotas'' mientras 86.986 + usted depura su configuración. 86.987 +\item[\rcitem{notify}{config}] La ruta a un fichero de configuración 86.988 + que contiene información de subscripción. Esto se mantiene separado 86.989 + del \hgrc\ principal para que usted pueda mantenerlo en un 86.990 + repositorio. La gente puede clonar ese repositorio, actualizar sus 86.991 + subscripciones, y empujar los cambios de vuelta a su servidor. 86.992 +\item[\rcitem{notify}{strip}] La cantidad de caracteres iniciales de 86.993 + separación de ruta a remover de la ruta del repositorio, al decidir 86.994 + si un repositorio tiene subscriptores. Por ejemplo, si los 86.995 + repositorios en su servidor están en \dirname{/home/hg/repos}, y 86.996 + \hgext{notify} está trabajando con un repositorio llamado 86.997 + \dirname{/home/hg/repos/shared/test}, fijar \rcitem{notify}{strip} a 86.998 + \texttt{4} hará que \hgext{notify} elimine las partes iniciales de 86.999 + la ruta hasta \dirname{shared/test}, y asociará los subscriptores 86.1000 + frente a dicha ruta. 86.1001 +\item[\rcitem{notify}{template}] El texto de plantilla a usar cuando 86.1002 + se envíen mensajes. Especifica los contenidos de la cabecera del 86.1003 + mensaje y el cuerpo del mismo. 86.1004 +\item[\rcitem{notify}{maxdiff}] El número máximo de líneas de datos de 86.1005 + diff a añadir al final de un mensaje. Si la longitud de un diff es 86.1006 + mayor a eso, se trunca. Por defecto, está fijado en 300. Fije esto a 86.1007 + \texttt{0} para omitir los diffs en los correos de notificación. 86.1008 +\item[\rcitem{notify}{sources}] Una lista de fuentes de conjuntos de 86.1009 + cambios a considerar. Esto le permite a usted indicar a 86.1010 + \hgext{notify} para que sólo envíe correos acerca de cambios que 86.1011 + usuarios remotos hayan empujado al repositorio vía un servidor, por 86.1012 + ejemplo. Vea la sección~\ref{sec:hook:sources} para las fuentes que 86.1013 + usted puede especificar aquí. 86.1014 +\end{itemize} 86.1015 + 86.1016 +Si usted fija el ítem \rcitem{web}{baseurl} en la sección 86.1017 +\rcsection{web}, usted lo puede usar en una plantilla; estará 86.1018 +disponible como \texttt{webroot}. 86.1019 + 86.1020 +A continuación se presenta un ejemplo completo de configuración para 86.1021 +el gancho \hgext{notify}. 86.1022 +\begin{codesample2} 86.1023 + [notify] 86.1024 + # enviar correo 86.1025 + test = false 86.1026 + # datos de subscriptores están en el repositorio notify 86.1027 + config = /home/hg/repos/notify/notify.conf 86.1028 + # repos están en /home/hg/repos on server, así que elimine 4 86.1029 + # caracteres"/" 86.1030 + strip = 4 86.1031 + template = X-Hg-Repo: \{webroot\} 86.1032 + Subject: \{webroot\}: \{desc|firstline|strip\} 86.1033 + From: \{author\} 86.1034 + 86.1035 + changeset \{node|short\} in \{root\} 86.1036 + details: \{baseurl\}\{webroot\}?cmd=changeset;node=\{node|short\} 86.1037 + description: 86.1038 + \{desc|tabindent|strip\} 86.1039 + 86.1040 + [web] 86.1041 + baseurl = http://hg.example.com/ 86.1042 +\end{codesample2} 86.1043 + 86.1044 +Esto producirá un mensaje que se verá como el siguiente: 86.1045 +\begin{codesample2} 86.1046 + X-Hg-Repo: tests/slave 86.1047 + Subject: tests/slave: Handle error case when slave has no buffers 86.1048 + Date: Wed, 2 Aug 2006 15:25:46 -0700 (PDT) 86.1049 + 86.1050 + changeset 3cba9bfe74b5 in /home/hg/repos/tests/slave 86.1051 + details: http://hg.example.com/tests/slave?cmd=changeset;node=3cba9bfe74b5 86.1052 + description: 86.1053 + Handle error case when slave has no buffers 86.1054 + diffs (54 lines): 86.1055 + 86.1056 + diff -r 9d95df7cf2ad -r 3cba9bfe74b5 include/tests.h 86.1057 + --- a/include/tests.h Wed Aug 02 15:19:52 2006 -0700 86.1058 + +++ b/include/tests.h Wed Aug 02 15:25:26 2006 -0700 86.1059 + @@ -212,6 +212,15 @@ static __inline__ void test_headers(void *h) 86.1060 + [...snip...] 86.1061 +\end{codesample2} 86.1062 + 86.1063 +\subsubsection{Pruebas y resolución de problemas} 86.1064 + 86.1065 +No olvide que por defecto, la extensión \hgext{notify} \emph{no 86.1066 +enviará ningún correo electrónico} hasta que usted la configure 86.1067 +explícitamente para hacerlo, fijando el valor de \rcitem{notify}{test} 86.1068 +a \texttt{false}. Hasta que usted haga eso, simplemente se imprimirá 86.1069 +el mensaje que se \emph{enviaría}. 86.1070 + 86.1071 +\section{Información para escritores de ganchos} 86.1072 +\label{sec:hook:ref} 86.1073 + 86.1074 +\subsection{Ejecución de ganchos internos} 86.1075 + 86.1076 +Un gancho interno es llamado con argumentos de la siguiente forma: 86.1077 +\begin{codesample2} 86.1078 + def myhook(ui, repo, **kwargs): 86.1079 + pass 86.1080 +\end{codesample2} 86.1081 +El parámetro \texttt{ui} es un objeto \pymodclass{mercurial.ui}{ui}. 86.1082 +El parámetro \texttt{repo} es un objeto 86.1083 +\pymodclass{mercurial.localrepo}{localrepository}. Los nombres y 86.1084 +valores de los parámetros en \texttt{**kwargs} dependen del gancho que 86.1085 +se invoque, con las siguientes características en común: 86.1086 +\begin{itemize} 86.1087 +\item Si hay un parámetro llamado \texttt{node} o 86.1088 + \texttt{parent\emph{N}}, contendrá un ID hexadecimal de un conjunto 86.1089 + de cambios. La cadena vacía es usada para representar un 86.1090 + ``ID de conjunto de cambios nulo'' en vez de una cadena de ceros. 86.1091 +\item Si hay un parámetro llamado \texttt{url}, contendrá la URL de un 86.1092 + repositorio remoto, si puede ser determinada. 86.1093 +\item Los parámetros booleanos son representados como objetos 86.1094 + \texttt{bool} de Python. 86.1095 +\end{itemize} 86.1096 + 86.1097 +Un gancho interno es ejecutado sin cambiar el directorio de trabajo 86.1098 +del proceso (a diferencia de los ganchos externos, que son ejecutados 86.1099 +desde la raíz del repositorio). El gancho no debe cambiar el 86.1100 +directorio de trabajo del proceso, porque esto haría que falle 86.1101 +cualquier llamada que se haga a la API de Mercurial. 86.1102 + 86.1103 +Si un gancho retorna el valor booleano ``false''\ndt{Falso.}, se 86.1104 +considera que éste tuvo éxito. Si retorna 86.1105 +``true''\ndt{Verdadero.} o genera una excepción, se considera que 86.1106 +ha fallado. Una manera útil de pensar en esta convención de llamado es 86.1107 +``dígame si usted falló''. 86.1108 + 86.1109 +Note que los IDs de conjuntos de cambios son pasados a los ganchos de 86.1110 +Python como cadenas hexadecimales, no como los hashes binarios que la 86.1111 +API de Mercurial usa normalmente. Para convertir un hash de 86.1112 +hexadecimal a binario, use la función \pymodfunc{mercurial.node}{bin}. 86.1113 + 86.1114 +\subsection{Ejecución de ganchos externos} 86.1115 + 86.1116 +Un gancho externo es pasado al intérprete de comandos del usuario bajo 86.1117 +el cual se ejecuta Mercurial. Las características del intérprete, como 86.1118 +sustitución de variables y redirección de comandos, están disponibles. 86.1119 +El gancho es ejecutado desde el directorio raíz del repositorio 86.1120 +(a diferencia de los ganchos internos, que se ejecutan desde el mismo 86.1121 +directorio en que Mercurial fue ejecutado). 86.1122 + 86.1123 +Los parámetros para el gancho se pasan como variables de entorno. El 86.1124 +nombre de cada variable de entorno se pasa a mayúsculas y se le añade 86.1125 +el prefijo ``\texttt{HG\_}''. Por ejemplo, si el nombre de un 86.1126 +parámetro es ``\texttt{node}'', el nombre de la variable de entorno 86.1127 +que almacena el parámetro se llamará ``\texttt{HG\_NODE}''. 86.1128 + 86.1129 +Un parámetro booleano se representa con la cadena ``\texttt{1}'' para 86.1130 +``true'', ``\texttt{0}'' para ``false''. Si una variable se llama 86.1131 +\envar{HG\_NODE}, \envar{HG\_PARENT1} o \envar{HG\_PARENT2}, 86.1132 +contendrá un ID de conjunto de cambios representado como una cadena 86.1133 +hexadecimal. La cadena vacía es usada para representar un ``ID de 86.1134 +conjunto de cambios nulo'' en vez de una cadena de ceros. Si una 86.1135 +variable de entorno se llama \envar{HG\_URL}, contendrá la URL de un 86.1136 +repositorio remoto, si puede ser determinada. 86.1137 + 86.1138 +Si un gancho termina con un código de salida de cero, se considera que 86.1139 +tuvo éxito. Si termina con un código de salida diferente de cero, se 86.1140 +considera que falló. 86.1141 + 86.1142 +\subsection{Averiguar de dónde vienen los conjuntos de cambios} 86.1143 +%TODO los trae la cigüeña. De París. Y quedan debajo de una col. 86.1144 + 86.1145 +Un gancho que involucra la transferencia de conjuntos de cambios entre 86.1146 +un repositorio local y otro puede ser capaz de averiguar información 86.1147 +acerca de ``el otro lado''. Mercurial sabe \emph{cómo} son 86.1148 +transferidos los conjuntos de cambios, y en muchos casos también desde 86.1149 +o hacia donde están siendo transferidos. 86.1150 + 86.1151 +\subsubsection{Fuentes de conjuntos de cambios} 86.1152 +\label{sec:hook:sources} 86.1153 + 86.1154 +Mercurial le indicará a un gancho cuáles son, o fueron, los medios 86.1155 +usados para transferir los conjuntos de cambios entre repositorios. 86.1156 +Esta información es provista por Mercurial en un parámetro Python 86.1157 +llamado \texttt{source}\ndt{Fuente.}, o una variable de entorno 86.1158 +llamada \envar{HG\_SOURCE}. 86.1159 + 86.1160 +\begin{itemize} 86.1161 +\item[\texttt{serve}] Los conjuntos de cambios son transferidos desde 86.1162 + o hacia un repositorio remoto a través de http o ssh. 86.1163 +\item[\texttt{pull}] Los conjuntos de cambios son transferidos vía una 86.1164 + operación de jalado de un repositorio a otro. 86.1165 +\item[\texttt{push}] Los conjuntos de cambios son transferidos vía un 86.1166 + empuje de un repositorio a otro. 86.1167 +\item[\texttt{bundle}] Los conjuntos de cambios son transferidos desde 86.1168 + %TODO bundle 86.1169 + o hacia un paquete. 86.1170 +\end{itemize} 86.1171 + 86.1172 +\subsubsection{A dónde van los cambios---URLs de repositorios remotos} 86.1173 +\label{sec:hook:url} 86.1174 +%TODO al cielo? no, ésos son los perros 86.1175 + 86.1176 +Cuando es posible, Mercurial le indicará a los ganchos la ubicación de 86.1177 +``el otro lado'' de una actividad que transfiera datos de conjuntos de 86.1178 +cambios entre repositorios. Esto es provisto por Mercurial en un 86.1179 +parámetro Python llamado \texttt{url}, o en una variable de entorno 86.1180 +llamada \envar{HG\_URL}. 86.1181 + 86.1182 +No siempre esta información está disponible. Si un gancho es invocado 86.1183 +un repositorio que es servido a través de http o ssh, Mercurial no 86.1184 +puede averiguar dónde está el repositorio remoto, pero puede saber 86.1185 +desde dónde se conecta el cliente. En esos casos, la URL tendrá una de 86.1186 +las siguientes formas: 86.1187 +\begin{itemize} 86.1188 +\item \texttt{remote:ssh:\emph{ip-address}}---cliente ssh remoto, en 86.1189 + la dirección IP dada. 86.1190 +\item \texttt{remote:http:\emph{ip-address}}---cliente remoto http, en 86.1191 + la dirección IP dada. Si el cliente está usando SSL, tendrá la forma 86.1192 + \texttt{remote:https:\emph{ip-address}}. 86.1193 +\item Vacío---no se pudo descubrir información acerca del cliente 86.1194 + remoto. 86.1195 +\end{itemize} 86.1196 + 86.1197 +\section{Referencia de ganchos} 86.1198 + 86.1199 +\subsection{\hook{changegroup}---luego de añadir conjuntos de cambios 86.1200 +remotos} 86.1201 +\label{sec:hook:changegroup} 86.1202 + 86.1203 +Este gancho es ejecutado luego de que un grupo de conjuntos de cambios 86.1204 +preexistentes ha sido añadido al repositorio, por ejemplo vía un 86.1205 +\hgcmd{pull} o \hgcmd{unbundle}. Este gancho es ejecutado una vez por 86.1206 +cada operación que añade uno o más conjuntos de cambios. Este gancho 86.1207 +se diferencia del gancho \hook{incoming}, que es ejecutado una vez por 86.1208 +cada conjunto de cambios, sin importar si los cambios llegan en grupo. 86.1209 + 86.1210 +Algunos usos posibles para este gancho includen el probar o ensamblar 86.1211 +los conjuntos de cambios añadidos, actualizar una base de datos de 86.1212 +fallos, o notificar a subscriptores de que el repositorio contiene 86.1213 +nuevos cambios. 86.1214 + 86.1215 +Parámetros para este gancho: 86.1216 +\begin{itemize} 86.1217 +\item[\texttt{node}] Un ID de conjunto de cambios. El ID del primer conjunto 86.1218 + de cambios que fue añadido en el grupo. Todos los conjuntos de 86.1219 + cambios entre éste y la punta 86.1220 + %TODO mirar qué hacer con el índice 86.1221 + \index{tags!\texttt{tip}}(\texttt{tip}), inclusive, fueron añadidos 86.1222 + %TODO unbundle 86.1223 + por un único jalado (\hgcmd{pull}), empuje (\hgcmd{push}) o \hgcmd{unbundle}. 86.1224 +\item[\texttt{source}] Una cadena. La fuente de estos cambios. Vea la 86.1225 + sección~\ref{sec:hook:sources} para más detalles. 86.1226 +\item[\texttt{url}] Una URL. La ubicación del repositorio remoto, si 86.1227 + es conocida. Vea la sección~\ref{sec:hook:url} para más información. 86.1228 +\end{itemize} 86.1229 + 86.1230 +Veta también: \hook{incoming} (sección~\ref{sec:hook:incoming}), 86.1231 +\hook{prechangegroup} (sección~\ref{sec:hook:prechangegroup}), 86.1232 +\hook{pretxnchangegroup} (sección~\ref{sec:hook:pretxnchangegroup}) 86.1233 + 86.1234 +\subsection{\hook{commit}---luego de la creación de un nuevo conjunto 86.1235 +de cambios} 86.1236 +\label{sec:hook:commit} 86.1237 + 86.1238 +Este gancho es ejecutado luego de la creación de un nuevo conjunto de 86.1239 +cambios. 86.1240 + 86.1241 +Parámetros para este gancho: 86.1242 +\begin{itemize} 86.1243 +\item[\texttt{node}] Un ID de conjunto de cambios. El ID de conjunto 86.1244 + de cambios del conjunto de cambios que acabó de ser consignado. 86.1245 +\item[\texttt{parent1}] Un ID de conjunto de cambios. El ID de 86.1246 + conjunto de cambios del primer padre del conjunto de cambios que 86.1247 + acaba de ser consignado. 86.1248 +\item[\texttt{parent2}] Un ID de conjunto de cambios. El ID de 86.1249 + conjunto de cambios del segundo padre del conjunto de cambios que 86.1250 + acaba de ser consignado. 86.1251 +\end{itemize} 86.1252 + 86.1253 +Vea también: \hook{precommit} (sección~\ref{sec:hook:precommit}), 86.1254 +\hook{pretxncommit} (sección~\ref{sec:hook:pretxncommit}) 86.1255 + 86.1256 +\subsection{\hook{incoming}---luego de que un conjunto de cambios 86.1257 +remoto es añadido} 86.1258 +\label{sec:hook:incoming} 86.1259 + 86.1260 +Este gancho es ejecutado luego de que un conjunto de cambios 86.1261 +preexistente ha sido añadido al repositorio, por ejemplo, vía un 86.1262 +\hgcmd{push}. Si un grupo de conjuntos de cambios fue añadido en una 86.1263 +sola operación, este gancho es ejecutado una vez por cada conjunto de 86.1264 +cambios añadido. 86.1265 + 86.1266 +Usted puede usar este gancho para los mismos fines que el gancho 86.1267 +\hook{changegroup} (sección~\ref{sec:hook:changegroup}); simplemente 86.1268 +algunas veces es más conveniente ejecutar un gancho una vez por cada 86.1269 +grupo de conjuntos de cambios, mientras que otras es más útil correrlo 86.1270 +por cada conjunto de cambios. 86.1271 + 86.1272 +Parámetros para este gancho: 86.1273 +\begin{itemize} 86.1274 +\item[\texttt{node}] Un ID de conjunto de cambios. El ID del conjunto 86.1275 + de cambios recién añadido. 86.1276 +\item[\texttt{source}] Una cadena. La fuente de estos cambios. Vea la 86.1277 + sección~\ref{sec:hook:sources} para más detalles. 86.1278 +\item[\texttt{url}] Una URL. La ubicación del repositorio remoto, si 86.1279 + es conocida. Vea la sección~\ref{sec:hook:url} para más información. 86.1280 +\end{itemize} 86.1281 + 86.1282 +Vea también: \hook{changegroup} (sección~\ref{sec:hook:changegroup}) 86.1283 +\hook{prechangegroup} (sección~\ref{sec:hook:prechangegroup}), 86.1284 +\hook{pretxnchangegroup} (sección~\ref{sec:hook:pretxnchangegroup}) 86.1285 + 86.1286 +\subsection{\hook{outgoing}---luego de la propagación de los conjuntos 86.1287 +de cambios} 86.1288 +\label{sec:hook:outgoing} 86.1289 + 86.1290 +Este gancho es ejecutado luego de que un grupo de conjuntos de cambios 86.1291 +ha sido propagado fuera de éste repositorio, por ejemplo por un 86.1292 +comando \hgcmd{push} o \hgcmd{bundle}. 86.1293 + 86.1294 +Un uso posible para este gancho es notificar a los administradores que 86.1295 +los cambios han sido jalados. 86.1296 + 86.1297 +Parámetros para este gancho: 86.1298 +\begin{itemize} 86.1299 +\item[\texttt{node}] Un ID de conjunto de cambios. El ID del primer conjunto 86.1300 + de cambios del grupo que fue enviado. 86.1301 +\item[\texttt{source}] Una cadena. La fuente de la operación (vea la 86.1302 + sección~\ref{sec:hook:sources}). Si un cliente remoto jaló cambios 86.1303 + de este repositorio, \texttt{source} será \texttt{serve}. Si el 86.1304 + cliente que obtuvo los cambios desde este repositorio era local, 86.1305 + \texttt{source} será \texttt{bundle}, \texttt{pull}, o 86.1306 + \texttt{push}, dependiendo de la operación que llevó a cabo el 86.1307 + cliente. 86.1308 +\item[\texttt{url}] Una URL. La ubicación del repositorio remoto, si 86.1309 + es conocida. Vea la sección~\ref{sec:hook:url} para más información. 86.1310 +\end{itemize} 86.1311 + 86.1312 +Vea también: \hook{preoutgoing} (sección~\ref{sec:hook:preoutgoing}) 86.1313 + 86.1314 +\subsection{\hook{prechangegroup}---antes de empezar la adición de 86.1315 +conjuntos de cambios remotos} 86.1316 +\label{sec:hook:prechangegroup} 86.1317 + 86.1318 +Este gancho de control es ejecutado antes de que Mercurial empiece a 86.1319 +añadir un grupo de conjuntos de cambios de otro repositorio. 86.1320 + 86.1321 +Este gancho no tiene ninguna información acerca de los conjuntos de 86.1322 +cambios que van a ser añadidos, porque es ejecutado antes de que se 86.1323 +permita que empiece la transmisión de dichos conjuntos de cambios. Si 86.1324 +este gancho falla, los conjuntos de cambios no serán transmitidos. 86.1325 + 86.1326 +Un uso para este gancho es prevenir que se añadan cambios externos a un 86.1327 +repositorio. Por ejemplo, usted podría usarlo para ``congelar'' 86.1328 +temporal o permanentemente una rama ubicada en un servidor para que 86.1329 +los usuarios no puedan empujar cambios a ella, y permitiendo al mismo 86.1330 +tiempo modificaciones al repositorio por parte de un administrador 86.1331 +local. 86.1332 + 86.1333 +Parámetros para este gancho: 86.1334 +\begin{itemize} 86.1335 +\item[\texttt{source}] Una cadena. La fuente de estos cambios. Vea la 86.1336 + sección~\ref{sec:hook:sources} para más detalles. 86.1337 +\item[\texttt{url}] Una URL. La ubicación del repositorio remoto, si 86.1338 + es conocida. Vea la sección~\ref{sec:hook:url} para más información. 86.1339 +\end{itemize} 86.1340 + 86.1341 +Vea también: \hook{changegroup} (sección~\ref{sec:hook:changegroup}), 86.1342 +\hook{incoming} (sección~\ref{sec:hook:incoming}), , 86.1343 +\hook{pretxnchangegroup} (sección~\ref{sec:hook:pretxnchangegroup}) 86.1344 + 86.1345 +\subsection{\hook{precommit}---antes de iniciar la consignación de un 86.1346 +conjunto de cambios} 86.1347 +\label{sec:hook:precommit} 86.1348 + 86.1349 +Este gancho es ejecutado antes de que Mercurial inicie la consignación 86.1350 +de un nuevo conjunto de cambios. Es ejecutado antes de que Mercurial 86.1351 +tenga cualquier de los metadatos para la consignación, como los 86.1352 +ficheros a ser consignados, el mensaje de consignación, o la fecha de 86.1353 +consignación. 86.1354 + 86.1355 +Un uso para este gancho es deshabilitar la capacidad de consignar 86.1356 +nuevos conjuntos de cambios, pero permitiendo conjuntos de cambios 86.1357 +entrantes. Otro es ejecutar un proceso de ensamble/compilación o 86.1358 +prueba, y permitir la consignación sólo si el ensamble/compilación o 86.1359 +prueba tiene éxito. 86.1360 + 86.1361 +Parámetros para este gancho: 86.1362 +\begin{itemize} 86.1363 + \item[\texttt{parent1}] Un ID de conjunto de cambios. El ID de 86.1364 + conjunto de cambios del primer padre del directorio de trabajo. 86.1365 +\item[\texttt{parent2}] Un ID de conjunto de cambios. El ID de 86.1366 + conjunto de cambios del segundo padre del directorio de trabajo. 86.1367 +\end{itemize} 86.1368 +Si la consignación continúa, los padres del directorio de trabajo se 86.1369 +convertirán en los padres del nuevo conjunto de cambios. 86.1370 + 86.1371 +Vea también: \hook{commit} (sección~\ref{sec:hook:commit}), 86.1372 +\hook{pretxncommit} (sección~\ref{sec:hook:pretxncommit}) 86.1373 + 86.1374 +\subsection{\hook{preoutgoing}---antes de empezar la propagación de 86.1375 +conjuntos de cambios} 86.1376 +\label{sec:hook:preoutgoing} 86.1377 + 86.1378 +Este gancho es ejecutado antes de que Mercurial conozca las 86.1379 +identidades de los conjuntos de cambios que deben ser transmitidos. 86.1380 + 86.1381 +Un uso para este gancho es evitar que los cambios sean transmitidos a 86.1382 +otro repositorio. 86.1383 + 86.1384 +Parámetros para este gancho: 86.1385 +\begin{itemize} 86.1386 + \item[\texttt{source}] Una cadena. La fuente la operación que está 86.1387 + tratando de obtener cambios de éste repositorio (vea 86.1388 + la sección~\ref{sec:hook:sources}). Revise la documentación para 86.1389 + el parámetro \texttt{source} del gancho \hook{outgoing}, en la 86.1390 + sección~\ref{sec:hook:outgoing}, para ver los posibles valores de 86.1391 + este parámetro. 86.1392 +\item[\texttt{url}] Una URL. La ubicación del repositorio remoto, si 86.1393 + es conocida. Vea la sección~\ref{sec:hook:url} para más información. 86.1394 +\end{itemize} 86.1395 + 86.1396 +Vea también: \hook{outgoing} (sección~\ref{sec:hook:outgoing}) 86.1397 + 86.1398 +\subsection{\hook{pretag}---antes de etiquetar un conjunto de cambios} 86.1399 +\label{sec:hook:pretag} 86.1400 + 86.1401 +Este gancho de control es ejecutado antes de la creación de una 86.1402 +etiqueta. Si el gancho termina exitosamente, la creación de la 86.1403 +etiqueta continúa. Si el gancho falla, no se crea la etiqueta. 86.1404 + 86.1405 +Parámetros para este gancho: 86.1406 +\begin{itemize} 86.1407 +\item[\texttt{local}] Un booleano. Indica si la etiqueta es local a 86.1408 + ésta instancia del repositorio (p.e.~almacenado en 86.1409 + \sfilename{.hg/localtags}) o administrado por Mercurial (almacenado 86.1410 + en \sfilename{.hgtags}). 86.1411 +\item[\texttt{node}] Un ID de conjunto de cambios. El ID del conjunto 86.1412 + de cambios a etiquetar. 86.1413 +\item[\texttt{tag}] Una cadena. El nombre de la etiqueta por crear. 86.1414 +\end{itemize} 86.1415 + 86.1416 +Si la etiqueta que se va a crear se encuentra bajo control de 86.1417 +revisiones, los ganchos \hook{precommit} y \hook{pretxncommit} 86.1418 +(secciones~\ref{sec:hook:commit} y~\ref{sec:hook:pretxncommit}) 86.1419 +también serán ejecutados. 86.1420 + 86.1421 +Vea también: \hook{tag} (sección~\ref{sec:hook:tag}) 86.1422 + 86.1423 +\subsection{\hook{pretxnchangegroup}---antes de completar la adición 86.1424 +de conjuntos de cambios remotos} 86.1425 +\label{sec:hook:pretxnchangegroup} 86.1426 + 86.1427 +Este gancho de control es ejecutado antes de una transacción---la que 86.1428 +maneja la adición de un grupo de conjuntos de cambios nuevos desde 86.1429 +fuera del repositorio---se complete. Si el gancho tiene éxito, la 86.1430 +transacción se completa, y todos los conjuntos de cambios se vuelven 86.1431 +permanentes dentro de este repositorio. Si el gancho falla, la 86.1432 +transacción es deshecha, y los datos para los conjuntos de cambios son 86.1433 +eliminados. 86.1434 + 86.1435 +Este gancho puede acceder a los metadatos asociados con los conjuntos 86.1436 +de cambios casi añadidos, pero no debe hacer nada permanente con estos 86.1437 +datos. Tampoco debe modificar el directorio de trabajo. 86.1438 + 86.1439 +Mientras este gancho está corriendo, si otro proceso Mercurial accesa 86.1440 +el repositorio, podrá ver los conjuntos de cambios casi añadidos como 86.1441 +si fueran permanentes. Esto puede llevar a condiciones de carrera si 86.1442 +usted no toma precauciones para evitarlas. 86.1443 + 86.1444 +Este gancho puede ser usado para examinar automáticamente un grupo de 86.1445 +conjuntos de cambios. Si el gancho falla, todos los conjuntos de 86.1446 +cambios son ``rechazados'' cuando la transacción se deshace. 86.1447 + 86.1448 +Parámetros para este gancho: 86.1449 +\begin{itemize} 86.1450 + \item[\texttt{node}] Un ID de conjunto de cambios. El ID del primer 86.1451 + conjunto de cambios que fue añadido en el grupo. Todos los 86.1452 + conjuntos de cambios entre éste y el 86.1453 + \index{tags!\texttt{tip}}\texttt{tip}, inclusive, fueron añadidos 86.1454 + por un único \hgcmd{pull}, \hgcmd{push} o \hgcmd{unbundle}. 86.1455 +\item[\texttt{source}] Una cadena. La fuente de estos cambios. Vea la 86.1456 + sección~\ref{sec:hook:sources} para más detalles. 86.1457 +\item[\texttt{url}] Una URL. La ubicación del repositorio remoto, si 86.1458 + es conocida. Vea la sección~\ref{sec:hook:url} para más información. 86.1459 +\end{itemize} 86.1460 + 86.1461 +Vea también: \hook{changegroup} (sección~\ref{sec:hook:changegroup}), 86.1462 +\hook{incoming} (sección~\ref{sec:hook:incoming}), 86.1463 +\hook{prechangegroup} (sección~\ref{sec:hook:prechangegroup}) 86.1464 + 86.1465 +\subsection{\hook{pretxncommit}---antes de completar la consignación 86.1466 +de un nuevo conjunto de cambios} 86.1467 +\label{sec:hook:pretxncommit} 86.1468 + 86.1469 +Este gancho de control es ejecutado antes de que una transacción---que 86.1470 +maneja una nueva consignación---se complete. Si el gancho tiene éxito, 86.1471 +la transacción se completa y el conjunto de cambios se hace permanente 86.1472 +dentro de éste repositorio. Si el gancho falla, la transacción es 86.1473 +deshecha, y los datos de consignación son borrados. 86.1474 + 86.1475 +Este gancho tiene acceso a los metadatos asociados con el 86.1476 +prácticamente nuevo conjunto de cambios, pero no debería hacer nada 86.1477 +permanente con estos datos. Tampoco debe modificar el directorio de 86.1478 +trabajo. 86.1479 + 86.1480 +Mientras este gancho está corriendo, si otro proceso Mercurial accesa 86.1481 +éste repositorio, podrá ver el prácticamente nuevo conjunto de cambios 86.1482 +como si fuera permanente. Esto puede llevar a condiciones de carrera si 86.1483 +usted no toma precauciones para evitarlas. 86.1484 + 86.1485 +Parámetros para este gancho: 86.1486 +\begin{itemize} 86.1487 + \item[\texttt{node}] Un ID de conjunto de cambios. El ID del 86.1488 + conjunto de cambios recién consignado. 86.1489 +\item[\texttt{parent1}] Un ID de conjunto de cambios. El ID de 86.1490 + conjunto de cambios del primer padre del conjunto de cambios que 86.1491 + acaba de ser consignado. 86.1492 +\item[\texttt{parent2}] Un ID de conjunto de cambios. El ID de 86.1493 + conjunto de cambios del segundo padre del conjunto de cambios que 86.1494 + acaba de ser consignado. 86.1495 +\end{itemize} 86.1496 + 86.1497 +Vea también: \hook{precommit} (sección~\ref{sec:hook:precommit}) 86.1498 + 86.1499 +\subsection{\hook{preupdate}---antes de actualizar o fusionar el 86.1500 +directorio de trabajo} 86.1501 +\label{sec:hook:preupdate} 86.1502 + 86.1503 +Este gancho de control es ejecutado antes de actualizar o fusionar el 86.1504 +directorio de trabajo. Es ejecutado sólo si las revisiones usuales de 86.1505 +Mercurial antes de las actualizaciones determinan que la actualización 86.1506 +o fusión pueden proceder. Si el gancho termina exitosamente, la 86.1507 +actualización o fusión pueden proceder.; si falla, la actualización o 86.1508 +fusión no empiezan. 86.1509 + 86.1510 +Parámetros para este gancho: 86.1511 +\begin{itemize} 86.1512 +\item[\texttt{parent1}] Un ID de conjunto de cambios. El ID del 86.1513 + padre al que el directorio de trabajo será actualizado. Si se está 86.1514 + fusionando el directorio de trabajo, no cambiará este padre. 86.1515 +\item[\texttt{parent2}] Un ID de conjunto de cambios. Sólo está 86.1516 + definido si se está fusionando el directorio de trabajo. El ID de la 86.1517 + revisión con la cual está siendo fusionado el directorio de trabajo. 86.1518 +\end{itemize} 86.1519 + 86.1520 +Vea también: \hook{update} (sección~\ref{sec:hook:update}) 86.1521 + 86.1522 +\subsection{\hook{tag}---luego de etiquetar un conjunto de cambios} 86.1523 +\label{sec:hook:tag} 86.1524 + 86.1525 +Este gancho es ejecutado luego de la creación de una etiqueta. 86.1526 + 86.1527 +Parámetros para este gancho: 86.1528 +\begin{itemize} 86.1529 +\item[\texttt{local}] Un booleano. Indica si la etiqueta es local a 86.1530 + ésta instancia del repositorio (p.e.~almacenado en 86.1531 + \sfilename{.hg/localtags}) o administrado por Mercurial (almacenado 86.1532 + en \sfilename{.hgtags}). 86.1533 +\item[\texttt{node}] Un ID de conjunto de cambios. El ID del 86.1534 + conjunto de cambios que fue etiquetado. 86.1535 +\item[\texttt{tag}] Una cadena. El nombre de la etiqueta que fue 86.1536 + creada. 86.1537 +\end{itemize} 86.1538 + 86.1539 +Si la etiqueta creada está bajo control de revisiones, el gancho 86.1540 +\hook{commit} (sección~\ref{sec:hook:commit}) es ejecutado antes de 86.1541 +este gancho. 86.1542 + 86.1543 +Vea también: \hook{pretag} (sección~\ref{sec:hook:pretag}) 86.1544 + 86.1545 +\subsection{\hook{update}---luego de actualizar o fusionar el 86.1546 +directorio de trabajo} 86.1547 +\label{sec:hook:update} 86.1548 + 86.1549 +Este gancho es ejecutado después de una actualización o fusión en el 86.1550 +directorio de trabajo. Ya que una fusión puede fallar (si el comando 86.1551 +externo \command{hgmerge} no puede resolver los conflictos en un 86.1552 +fichero), este gancho indica si la actualización o fusión fueron 86.1553 +completados adecuadamente. 86.1554 + 86.1555 +\begin{itemize} 86.1556 +\item[\texttt{error}] Un booleano. Indica si la actualización o fusión 86.1557 + fue completada exitosamente. 86.1558 +\item[\texttt{parent1}] Un ID de conjunto de cambios. El ID del padre 86.1559 + al cual fue actualizado el directorio de trabajo. Si se fusionó el 86.1560 + directorio de trabajo, no se habrá cambiado este padre. 86.1561 +\item[\texttt{parent2}] Un ID de conjunto de cambios. Sólo está 86.1562 + definido si se fusionó el directorio de trabajo. El ID de la 86.1563 + revisión con la que fue fusionado el directorio de trabajo. 86.1564 +\end{itemize} 86.1565 + 86.1566 +Vea también: \hook{preupdate} (sección~\ref{sec:hook:preupdate}) 86.1567 + 86.1568 +%%% Local Variables: 86.1569 +%%% mode: latex 86.1570 +%%% TeX-master: "00book" 86.1571 +%%% End:
87.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 87.2 +++ b/es/htlatex.book Thu Jan 29 22:00:07 2009 -0800 87.3 @@ -0,0 +1,1 @@ 87.4 +../en/htlatex.book 87.5 \ No newline at end of file
88.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 88.2 +++ b/es/intro.tex Thu Jan 29 22:00:07 2009 -0800 88.3 @@ -0,0 +1,621 @@ 88.4 +\chapter{Introducción} 88.5 +\label{chap:intro} 88.6 + 88.7 +\section{Acerca del control de revisiones} 88.8 + 88.9 +El control de revisiones es el proceso de administrar diferentes 88.10 +versiones de una pieza de información. En su forma más simple es algo 88.11 +que la mayoría de gente hace a mano: cada vez que usted modifica un 88.12 +fichero, lo graba con un nuevo nombre que contiene un número, cada uno 88.13 +mayor que el anterior. 88.14 + 88.15 +Administrar manualmente muchas versiones de incluso sólo un fichero es una tarea 88.16 +propensa a errores, a pesar de que hace bastante tiempo hay 88.17 +herramientas que ayudan en este proceso. Las primeras herramientas 88.18 +para automatizar el control de revisiones fueron pensadas para que un 88.19 +usuario administrara un solo fichero. En las décadas pasadas, el 88.20 +alcance de las herramientas de control de revisiones ha ido aumentando 88.21 +considerablemente; ahora manejan muchos ficheros y facilitan el 88.22 +trabajo en conjunto de varias personas. Las mejores herramientas de 88.23 +control de revisiones de la actualidad no tienen problema con miles de 88.24 +personas trabajando en proyectos que consisten de cientos de miles de 88.25 +ficheros. 88.26 + 88.27 +\subsection{¿Por qué usar control de revisiones?} 88.28 + 88.29 +Hay muchas razones por las cuales usted o su equipo desearía usar una 88.30 +herramienta automática de control de revisiones para un proyecto. 88.31 +\begin{itemize} 88.32 +\item Llevar registro del historial y la evolución de su proyecto, para 88.33 + evitar hacer la tarea manualmente. Por cada cambio, tendrá una 88.34 + bitácora de \emph{quién} lo hizo; \emph{por qué} se hizo; 88.35 + \emph{cuándo} se hizo; y de \emph{qué} se trataba el cambio. 88.36 +\item Cuando trabaja con más personas, los programas de control de 88.37 + revisiones facilitan la colaboración. Por ejemplo, cuando varias 88.38 + personas hacen cambios potencialmente incompatibles de forma casi 88.39 + simultánea, el programa le ayudará a identificar y resolver tales 88.40 + conflictos. 88.41 +\item Puede ayudarle a recuperarse de equivocaciones. Si aplica un 88.42 + cambio que posteriormente se evidencia como un error, puede 88.43 + revertirlo a una versión previa a uno o muchos ficheros. De hecho, 88.44 + una herramienta \emph{realmente} buena, incluso puede ayudarle 88.45 + efectivamente a darse cuenta exactamente cuándo se introdujo el 88.46 + error (para más detalles ver la sección~\ref{sec:undo:bisect}). 88.47 +\item Le ayudará a trabajar simultáneamente, y a manejar las diferencias 88.48 + entre múltiples versiones de su proyecto. 88.49 +\end{itemize} 88.50 +La mayoría de estas razones son igualmente válidas ---por lo menos en 88.51 +teoría--- así esté trabajando en un proyecto solo usted, o con mucha gente. 88.52 + 88.53 +Algo fundamental acerca de lo práctico de un sistema de control de 88.54 +revisiones en estas dos escalas (``un hacker solitario'' y ``un equipo 88.55 +gigantesco'') es cómo se comparan los \emph{beneficios} con los 88.56 +\emph{costos}. Una herramienta de control de revisiones que sea 88.57 +difícil de entender o usar impondrá un costo alto. 88.58 + 88.59 +Un proyecto de quinientas personas es muy propenso a colapsar 88.60 +solamente con su peso inmediatamente sin una herramienta y un proceso 88.61 +de control de versiones. En este caso, el costo de usar control de 88.62 +revisiones ni siquiera se tiene en cuenta, puesto que \emph{sin} él, 88.63 +el fracaso está casi garantizado. 88.64 + 88.65 +Por otra parte, un ``arreglo rápido'' de una sola persona, excluiría 88.66 +la necesidad de usar una herramienta de control de revisiones, porque 88.67 +casi seguramente, el costo de usar una estaría cerca del costo del 88.68 +proyecto. ¿No es así? 88.69 + 88.70 +Mercurial soporta \emph{ambas} escalas de de desarrollo de manera 88.71 +única. Puede aprender lo básico en pocos minutos, y dado su bajo 88.72 +sobrecosto, puede aplicar el control de revisiones al proyecto más 88.73 +pequeño con facilidad. Su simplicidad significa que no tendrá que 88.74 +preocuparse por conceptos obtusos o secuencias de órdenes compitiendo 88.75 +por espacio mental con lo que sea que \emph{realmente} esté tratando 88.76 +de hacer. Al mismo tiempo, Mercurial tiene alto desempeño y su 88.77 +%TODO distribuida? en vez de p2p 88.78 +naturaleza peer-to-peer le permite escalar indoloramente para manejar 88.79 +grandes proyectos. 88.80 + 88.81 +Ninguna herramienta de control de revisiones puede salvar un 88.82 +proyecto mal administrado, pero la elección de herramientas puede 88.83 +hacer una gran diferencia en la fluidez con la cual usted puede 88.84 +trabajar en un proyecto. 88.85 + 88.86 +\subsection{La cantidad de nombres del control de revisiones} 88.87 + 88.88 +El control de revisiones es un campo amplio, tan amplio que no hay un 88.89 +acrónimo o nombre único. A continuación presentamos un listado de 88.90 +nombres comunes y acrónimos que se podrían encontrar: 88.91 +\begin{itemize} 88.92 +\item Control de revisiones (RCS) 88.93 +\item Manejo de Configuraciones de Programas (SCM), o administracón de 88.94 + configuraciones 88.95 +\item Administración de código fuente 88.96 +\item Control de Código Fuente, o Control de Fuentes 88.97 +\item Control de Versiones (VCS) 88.98 +\end{itemize} 88.99 +Algunas personas aducen que estos términos tienen significados 88.100 +diversos, pero en la práctica se sobreponen tanto que no hay una 88.101 +forma acordada o incluso adecuada de separarlos. 88.102 + 88.103 +\section{Historia resumida del control de revisiones} 88.104 + 88.105 +La herramienta de control de revisiones más antigua conocida es SCCS 88.106 +(Sistema de Control de Código), escrito por Marc Rochkind en Bell 88.107 +Labs, a comienzos de los setentas (1970s). SCCS operaba sobre ficheros 88.108 +individuales, y requería que cada persona que trabajara en el proyecto 88.109 +tuviera acceso a un espacio compartido en un solo sistema. Solamente 88.110 +una persona podía modificar un fichero en un momento dado; el 88.111 +arbitramiento del acceso a los ficheros se hacía con candados. Era 88.112 +común que la gente pusiera los candados a los ficheros, y que 88.113 +posteriormente olvidara quitarlos, impidiendo que otro pudiera 88.114 +modificar los ficheros en cuestión sin la intervención del 88.115 +administrador. 88.116 + 88.117 +Walter Tichy desarrolló una alternativa gratuita a SCCS a comienzos 88.118 +de los ochentas (1980s); llamó a su programa RCS (Sistema de Control de 88.119 +Revisiones). Al igual que SCCS, RCS requería que los desarrolladores 88.120 +trabajaran en un único espacio compartido y colocaran candados a los 88.121 +ficheros para evitar que varias personas los modificaran 88.122 +simultáneamente. 88.123 + 88.124 +Después en los ochenta, Dick Grune usó RCS como un bloque de 88.125 +construcción para un conjunto de guiones de línea de comando, que 88.126 +inicialmente llamó cmt, pero que renombró a CVS (Sistema Concurrente de 88.127 +Versiones). La gran innovación de CVS era que permitía a los 88.128 +desarrolladores trabajar simultáneamente de una forma más o menos 88.129 +independiente en sus propios espacios de trabajo. Los espacios de 88.130 +trabajo personales impedían que los desarrolladores se pisaran las 88.131 +mangueras todo el tiempo, situación común con SCCS y RCS. Cada 88.132 +desarrollador tenía una copia de todos los ficheros del proyecto y podía 88.133 +modificar sus copias independientemente, Tenían que fusionar sus 88.134 +ediciones antes de consignar los cambios al repositorio central. 88.135 + 88.136 +Brian Berliner tomó los scripts originales de Grune y los reescribió 88.137 +en~C, publicando en 1989 el código sobre el cual se ha 88.138 +desarrollado la versión moderna de CVS. CVS adquirió posteriormente 88.139 +la habilidad de operar sobre una conexión de red, dotándolo de una 88.140 +arquitectura, cliente/servidor. La arquitectura de CVS es 88.141 +centralizada; el historial del proyecto está únicamente en el 88.142 +repositorio central. Los espacios de trabajo de los clientes 88.143 +contienen únicamente copias recientes de las versiones de los 88.144 +ficheros, y pocos metadatos para indicar dónde está el servidor. CVS 88.145 +ha tenido un éxito enorme; Es probablemente el sistema de control de 88.146 +revisiones más extendido del planeta. 88.147 + 88.148 +A comienzos de los noventa~(1990s), Sun MicroSystems desarrollo un 88.149 +temprano sistema distribuido de control de revisiones llamado 88.150 +TeamWare. 88.151 +Un espacio de trabajo TeamWare contiene una copia completa del 88.152 +historial del proyecto. TeamWare no tiene la noción de repositorio 88.153 +central. (CVS se basaba en RCS para el almacenamiento de su historial; 88.154 +TeamWare usaba SCCS.) 88.155 + 88.156 +A medida que avanzaba la decada de los noventa, se empezó a 88.157 +evidenciar los problemas de CVS. Almacena cambios simultáneos a muchos 88.158 +ficheros de forma individual, en lugar de agruparlos como una 88.159 +operación única y atómica lógicamente. No maneja bien su jerarquía de 88.160 +ficheros; es fácil desordenar un repositorio al renombrar ficheros 88.161 +y directorios. Peor aún, su código fuente es difícil de leer y 88.162 +mantener, lo que hizo que su ``umbral de dolor'' para arreglar sus 88.163 +problemas arquitecturales fuera algo prohibitivo. 88.164 + 88.165 +En 2001, Jim Blandy y Karl Fogel, dos desarrolladores que habían 88.166 +trabajado en CVS, comenzaron un proyecto para reemplazarlo con una 88.167 +herramienta con mejor arquitectura y código más limpio. El resultado, 88.168 +Subversion, no se separó del modelo centralizado cliente/servidor de 88.169 +CVS, pero añadió consignaciones atómicas de varios ficheros, mejor 88.170 +manejo de espacios de nombres , y otras características que lo hacen 88.171 +mejor que CVS. Desde su versión inicial, ha ido creciendo en 88.172 +popularidad rápidamente. 88.173 + 88.174 +Más o menos en forma simultánea Graydon Hoare comenzó a trabajar en un 88.175 +ambicioso sistema distribuido de control de versiones que llamó 88.176 +Monotone. Mientras que Monotone se enfocaba a evitar algunas fallas de 88.177 +diseño de CVS con una arquitectura peer-to-peer, fue mucho más 88.178 +allá de las herramientas anteriores (y posteriores) de 88.179 +control de revisiones en varios aspectos innovadores. Usa hashes 88.180 +criptográficos como identificadores, y tiene una noción integral de 88.181 +``confianza'' para código de diversas fuentes. 88.182 + 88.183 +Mercurial nació en el 2005. Algunos de sus aspectos de de diseño 88.184 +fueron influenciados por Monotone, pero Mercurial se enfoca en la 88.185 +facilidad de uso, gran rendimiento y escalabilidad para proyectos muy 88.186 +grandes. 88.187 + 88.188 +\section{Tendencias en el control de revisiones} 88.189 + 88.190 +Ha habido una tendencia inconfundible en el desarrollo y uso de las herramientas 88.191 +de control de revisiones en las cuatro décadas pasadas, mientras la 88.192 +gente se ha hecho familiar con las capacidades de sus herramientas y 88.193 +se ha visto restringida por sus limitaciones. 88.194 + 88.195 +La primera generación comenzó administrando ficheros individuales en 88.196 +computadores por persona. A pesar de que tales herramientas 88.197 +representaron un avance importante frente al control de revisiones 88.198 +manual, su modelo de candados y la dependencia a un sólo computador 88.199 +los limitó a equipos de trabajo pequeños y acoplados. 88.200 + 88.201 +La segunda generación dejó atrás esas limitaciones moviéndose a 88.202 +arquitecturas centradas en redes, y administrando proyectos completos 88.203 +a la vez. A medida que los proyectos crecían, nacieron nuevos 88.204 +problemas. Con la necesidad de comunicación frecuente con los 88.205 +servidores, escalar estas máquinas se convirtió en un problema en 88.206 +proyectos realmente grandes. Las redes con poca estabilidad podrían 88.207 +impedir que usuarios remotos se conectaran al servidor. A medida que 88.208 +los 88.209 +proyectos de código abierto comenzaron a ofrecer acceso de sólo lectura 88.210 +de forma anónima a cualquiera, la gente sin permiso para consignar 88.211 +vio que no podían usar tales herramientas para interactuar en un 88.212 +proyecto de forma natural, puesto que no podían guardar sus cambios. 88.213 + 88.214 +La generación actual de herramientas de control de revisiones es 88.215 +peer-to-peer por naturaleza. Todos estos sistemas han eliminado la 88.216 +dependencia de un único servidor central, y han permitido que la 88.217 +gente distribuya sus datos de control de revisiones donde realmente se 88.218 +necesita. La colaboración a través de Internet ha cambiado las 88.219 +limitantes tecnológicas por la cuestión de elección y consenso. Las 88.220 +herramientas modernas pueden operar sin conexión indefinidamente y 88.221 +autónomamente, necesitando una conexión de red solamente para 88.222 +sincronizar los cambios con otro repositorio. 88.223 + 88.224 +\section{Algunas ventajas del control distribuido de revisiones} 88.225 + 88.226 +A pesar de que las herramientas para el control distribuido de 88.227 +revisiones lleva varios años siendo tan robustas y usables como la 88.228 +generación previa de sus contrapartes, algunas personas que usan las 88.229 +herramientas más antiguas no se han percatado de sus ventajas. Hay 88.230 +gran cantidad 88.231 +de situaciones en las cuales las herramientas distribuidas brillan 88.232 +frente a las centralizadas. 88.233 + 88.234 +Para un desarrollador individual, las herramientas distribuidas casi 88.235 +siempre son más rápidas que las centralizadas. Por una razón sencilla: 88.236 +Una herramienta centralizada necesita comunicarse por red para las 88.237 +operaciones más usuales, debido a que los metadatos se almacenan en 88.238 +una sola copia en el servidor central. Una herramienta distribuida 88.239 +almacena todos sus metadatos localmente. Con todo lo demás de la 88.240 +misma forma, comunicarse por red tiene un sobrecosto en una 88.241 +herramienta centralizada. No subestime el valor de una herramienta de 88.242 +respuesta rápida: Usted empleará mucho tiempo interactuando con su 88.243 +programa de control de revisiones. 88.244 + 88.245 +Las herramientas distribuidas son indiferentes a los caprichos de su 88.246 +infraestructura de servidores, de nuevo, debido a la replicación de 88.247 +metadatos en tantos lugares. Si usa un sistema centralizado y su 88.248 +servidor explota, ojalá los medios físicos de su copia de seguridad 88.249 +sean confiables, y que su última copia sea reciente y además 88.250 +funcione. Con una herramienta distribuida tiene tantas copias de 88.251 +seguridad disponibles como computadores de contribuidores. 88.252 + 88.253 +La confiabilidad de su red afectará las herramientas distribuidas de 88.254 +una forma mucho menor que a las herramientas centralizadas. Usted no puede 88.255 +siquiera usar una herramienta centralizada sin conexión de red, 88.256 +excepto por algunas órdenes muy limitadas. Con herramientas 88.257 +distribuidas, si sus conexión cae mientras usted está trabajando, 88.258 +podría nisiquiera darse cuenta. Lo único que que no podrá hacer es 88.259 +comunicarse con repositorios en otros computadores, algo que es 88.260 +relativamente raro comparado con las operaciones locales. Si tiene 88.261 +colaboradores remotos en su equipo, puede ser importante. 88.262 + 88.263 +\subsection{Ventajas para proyectos de código abierto} 88.264 + 88.265 +Si descubre un proyecto de código abierto y decide que desea comenzar 88.266 +a trabajar en él, y ese proyecto usa una herramienta de control 88.267 +distribuido de revisiones, usted es de inmediato un par con la gente que se 88.268 +considera el ``alma'' del proyecto. Si ellos publican sus 88.269 +repositorios, usted puede copiar inmediatamente el historial del proyecto, 88.270 +hacer cambios y guardar su trabajo, usando las mismas herramientas de 88.271 +la misma forma que ellos. En contraste, con una herramienta 88.272 +centralizada, usted debe usar el programa en un modo ``sólo lectura'' a 88.273 +menos que alguien le otorgue permisos para consignar cambios en el 88.274 +repositorio central. Hasta entonces, no podrá almacenar sus cambios y 88.275 +sus modificaciones locales correrán el riesgo de dañarse cuando trate 88.276 +de actualizar su vista del repositorio. 88.277 + 88.278 +\subsubsection{Las bifurcaciones (forks) no son un problema} 88.279 + 88.280 +Se ha mencionado que las herramientas de control distribuido de 88.281 +versiones albergan un riesgo a los proyectos de código abierto, puesto 88.282 +que se vuelve muy sencillo hacer una ``bifurcación''\ndt{fork.} del 88.283 +desarrollo del proyecto. Una bifurcación sucede cuando hay diferencias 88.284 +de opinión o actitud entre grupos de desarrolladores que desemboca en 88.285 +la decisión de la imposibilidad de continuar trabajando juntos. Cada 88.286 +parte toma una copia más o menos completa del código fuente del 88.287 +proyecto y toma su propio rumbo. 88.288 + 88.289 +En algunas ocasiones los líderes de las bifurcaciones reconcilian sus 88.290 +diferencias. Con un sistema centralizado de control de revisiones, el 88.291 +proceso \emph{técnico} de reconciliarse es doloroso, y se hace de 88.292 +forma muy manual. Usted tiene que decidir qué historial de revisiones va a 88.293 +``ganar'', e injertar los cambios del otro equipo en el árbol de alguna 88.294 +manera. Con esto usualmente se pierde algo o todo del historial de la 88.295 +revisión de alguna de las partes. 88.296 + 88.297 +Lo que las herramientas distribuidas hacen con respecto a las 88.298 +bifurcaciones, es que las bifurcaciones son la \emph{única} forma de 88.299 +desarrollar un proyecto. Cada cambio que usted hace es potencialmente 88.300 +un punto de bifurcación. La gran fortaleza de esta aproximación es que 88.301 +las herramientas distribuidas de control de revisiones tiene que ser 88.302 +bueno al \emph{fusionar} las bifurcaciones, porque las bifurcaciones 88.303 +son absolutamente fundamentales: pasan todo el tiempo. 88.304 + 88.305 +Si todas las porciones de trabajo que todos hacen, todo el tiempo, se 88.306 +enmarcan en términos de bifurcaciones y fusiones, entonces a aquello a 88.307 +lo que se refiere en el mundo del código abierto a una ``bifurcación'' 88.308 +se convierte \emph{puramente} en una cuestión social. Lo que hacen las 88.309 +herramientas distribuidas es \emph{disminuir} la posibilidad de una 88.310 +bifurcación porque: 88.311 +\begin{itemize} 88.312 +\item Eliminan la distinción social que imponen las herramientas 88.313 + centralizadas: aquélla entre miembros (personas con permiso de 88.314 + consignar) y forasteros (los que no tienen el permiso). 88.315 +\item Facilitan la reconciliación después de una bifurcación social, 88.316 + porque todo lo que concierne al programa de control de revisiones es 88.317 + una fusión. 88.318 +\end{itemize} 88.319 + 88.320 +Algunas personas se resisten a las herramientas distribuidas porque 88.321 +desean mantener control completo sobre sus proyectos, y creen que las 88.322 +herramientas centralizadas les dan tal control. En todo caso, si este 88.323 +es su parecer, y usted publica sus repositorios de CVS o Subversion, hay 88.324 +muchas herramientas disponibles que pueden obtener el historial 88.325 +completo (aunque sea lentamente) y recrearlo en otro sitio que usted no 88.326 +controla. Siendo así un control ilusorio, puesto que está impidiendo 88.327 +la fluidez de colaboración en lugar de prevenir que alguien se sienta 88.328 +impulsado a obtener una copia y hacer una bifurcación con su historial. 88.329 + 88.330 +\subsection{Ventajas para proyectos comerciales} 88.331 + 88.332 +Muchos proyectos comerciales tienen grupos de trabajo distribuidos 88.333 +alrededor del globo. Quienes contribuyen y están lejos de un 88.334 +repositorio central verán una ejecución más lenta de los comandos y tal 88.335 +vez menos confiabilidad. Los sistemas de control de revisión 88.336 +comerciales intentan amortiguar estos problemas con adiciones de 88.337 +replicación remota que usualmente son muy costosos y complicados de 88.338 +administrar. Un sistema distribuido no padece estos problemas. Mejor 88.339 +aún, puede colocar varios servidores autorizados, por ejemplo, uno por 88.340 +sitio, de tal forma que no haya comunicación redundante entre 88.341 +repositorios sobre enlaces de conexión costosos. 88.342 + 88.343 +Los sistemas de control de revisiones distribuidos tienden a ser poco 88.344 +escalables. No es inusual que costosos sistemas centralizados caigan 88.345 +ante la carga combinada de unas cuantas docenas de usuarios 88.346 +concurrentes. De nuevo, las respuestas típicas de replicación tienden 88.347 +a ser costosas y complejas de instalar y administrar. Dado que la 88.348 +carga en un servidor central---si es que tiene uno---es muchas veces 88.349 +menor con una herramienta distribuida (debido a que los datos están 88.350 +replicados en todas partes), un solo servidor económico puede tratar 88.351 +las necesidades de equipos mucho más grandes, y la replicación para 88.352 +balancear la carga se vuelve cosa de guiones. 88.353 + 88.354 +Si tiene un empleado en el campo, se beneficiará grandemente de un 88.355 +sistema distribuido de control de versiones al resolver problemas en 88.356 +el sitio del cliente. La herramienta le permitirá generar 88.357 +construcciones a la medida, probar diferentes arreglos de forma 88.358 +independiente y buscar de forma eficiente las fuentes de fallos en el 88.359 +historial y regresiones en los ambientes de los clientes, todo sin 88.360 +necesidad de conectarse al servidor de su compañía. 88.361 + 88.362 +\section{¿Por qué elegir Mercurial?} 88.363 + 88.364 +Mercurial cuenta con un conjunto único de propiedades que lo hacen 88.365 +una elección particularmente buena como sistema de control de 88.366 +revisiones, puesto que: 88.367 +\begin{itemize} 88.368 +\item Es fácil de aprender y usar. 88.369 +\item Es liviano. 88.370 +\item Escala de forma excelente. 88.371 +\item Es fácil de acondicionar. 88.372 +\end{itemize} 88.373 + 88.374 +Si los sistemas de control de revisiones le son familiares, debería 88.375 +estar listo para usar Mercurial en menos de cinco minutos. Si no, sólo va a 88.376 +tomar unos pocos minutos más. Las órdenes de Mercurial y su conjunto 88.377 +de características son uniformes y consistentes generalmente, y basta 88.378 +con que siga unas pocas reglas generales en lugar de un montón de 88.379 +excepciones. 88.380 + 88.381 +En un proyecto pequeño, usted puede comenzar a trabajar con Mercurial en 88.382 +pocos momentos. Crear nuevos cambios y ramas, transferir cambios (localmente 88.383 +o por la red); y las operaciones relacionadas con el estado y el 88.384 +historial son rápidas. Mercurial buscar ser ligero y no incomodar en su 88.385 +camino combinando poca sobrecarga cognitiva con operaciones 88.386 +asombrosamente rápidas. 88.387 + 88.388 +La utilidad de Mercurial no se limita a proyectos pequeños: está 88.389 +siendo usado por proyectos con centenas de miles de contribuyentes, 88.390 +cada uno conteniendo decenas de miles de ficheros y centenas de 88.391 +megabytes de código fuente 88.392 + 88.393 +Si la funcionalidad básica de Mercurial no es suficiente para usted, 88.394 +es muy fácil extenderlo. Mercurial se comporta muy bien con tareas de 88.395 +scripting y su limpieza interna junto con su implementación en Python 88.396 +permiten añadir características fácilmente en forma de extensiones. 88.397 +Hay un buen número de extensiones útiles y populares en este momento, 88.398 +desde ayudar a identificar fallos hasta mejorar su desempeño. 88.399 + 88.400 +\section{Comparación de Mercurial con otras herramientas} 88.401 + 88.402 +Antes de leer, por favor tenga en cuenta que esta sección 88.403 +necesariamente refleja mis propias experiencias, intereses y (tengo que 88.404 +decirlo) mis preferencias. He usado cada una de las herramientas de 88.405 +control de versiones listadas a continuación, y en muchos casos por 88.406 +varios años. 88.407 + 88.408 + 88.409 +\subsection{Subversion} 88.410 + 88.411 +Subversion es una herramienta de control de revisiones muy popular, 88.412 +desarrollada para reemplazar a CVS. Tiene una arquitectura 88.413 +centralizada tipo cliente/servidor. 88.414 + 88.415 +Subversion y Mercurial tienen comandos con nombres similares para hacer 88.416 +las mismas operaciones, por lo que si le son familiares en una, será 88.417 +sencillo aprender a usar la otra. Ambas herramientas son portables en 88.418 +todos los sistemas operativos populares. 88.419 + 88.420 +Antes de la versión 1.5, Subversion no tenía soporte para fusiones. En 88.421 +el momento de la escritura, sus capcidades para llevar cuenta de las 88.422 +funciones son nuevas, 88.423 +\href{http://svnbook.red-bean.com/nightly/en/svn.branchmerge.advanced.html#svn.branchmerge.advanced.finalword}{complicadas 88.424 + y poco estables\ndt{buggy}}. 88.425 + 88.426 +Mercurial tiene una ventaja considerable en desempeño sobre 88.427 +Subversion en cualquier operación de control de revisiones que yo haya 88.428 +medido. He medido sus ventajas con factores desde dos hasta seis veces 88.429 +comparando con almacenamiento de ficheros \emph{ra\_local} 88.430 +Subversion~1.4.3, el cual es el método de acceso más rápido. En los 88.431 +escenarios más realistas incluyendo almacenamiento con la red de por 88.432 +medio, Subversion se encuentra en desventaja aún mayor. Dado que casi 88.433 +todas las órdenes de Subversion deben tratar con el servidor y 88.434 +Subversion no tiene utilidades de replicación adecuadas, la capacidad 88.435 +del servidor y el ancho de banda se convierten en cuellos de botella 88.436 +para proyectos modestamente grandes. 88.437 + 88.438 +Adicionalmente, Subversion tiene un sobrecosto considerable en 88.439 +almacenamiento para evitar transacciones por red en algunas 88.440 +operaciones, 88.441 +tales como encontrar ficheros modificados (\texttt{status}) y desplegar 88.442 +información frente a la revisión actual (\texttt{diff}). Como 88.443 +resultado, la copia de trabajo de Subversion termina siendo del mismo 88.444 +tamaño o más grande que un repositorio de Mercurial y el directorio de 88.445 +trabajo, a pesar de que el repositorio de Mercurial contiene el 88.446 +historial completo del proyecto. 88.447 + 88.448 +Subversion tiene soporte amplio de otras herramientas. Mercurial por 88.449 +ahora está bastante atrás en este aspecto. Esta diferencia está 88.450 +disminuyendo, y algunas de las herramientas GUI\ndt{Interfaz de 88.451 + Usuario Gráfica}, eclipsan sus equivalentes de Subversion. Al igual 88.452 +que Mercurial, Subversion tiene un excelente manual de usuario. 88.453 + 88.454 +Dado que Subversion no almacena el historial de revisiones en el 88.455 +cliente, es muy bueno para administrar proyectos que tienen muchos 88.456 +ficheros binarios grandes y opacos. Si consigna cincuenta revisiones 88.457 +de un fichero de 10MB que no es comprimible, el esapacio en el cliente 88.458 +de Subversion se mantendrá constante mientras que el espacio usado por 88.459 +cualquier Sistema Distribuido de Control de Revisiones crecerá 88.460 +rápidamente en proporción con el número de revisiones, debido a que 88.461 +las diferencias entre cada revisión es grande. 88.462 + 88.463 +Adicionalmente, generalmente es difícil o más bien, imposible mezclar 88.464 +diferentes versiones de un fichero binario. La habilidad de Subversion 88.465 +para permitirle al usuario poner una cerradura a un fichero, de modo 88.466 +que tenga un permiso exclusivo para consignar cambios, puede ser una 88.467 +ventaja significativa en un proyecto donde los ficheros binarios sean 88.468 +usados ampliamente. 88.469 + 88.470 +Mercurial puede importar el historial de revisiones de un repositorio 88.471 +de Subversion. También puede exportar el historial de revisiones a un 88.472 +repositorio de Subversion. De esta forma es sencillo ``dar un 88.473 +vistazo'' y usar Mercurial y Subversion en paralelo antes de decidirse 88.474 +a dar el paso. La conversión del historial es incremental, de modo 88.475 +que puede aplicar una conversión inicial, y después conversiones 88.476 +pequeñas y adicionales posteriormente para traer nuevos cambios. 88.477 + 88.478 +\subsection{Git} 88.479 + 88.480 +Git es una herramienta distribuida de control de revisiones 88.481 +desarrollada para administrar el arbol del kernel de Linux. Al igual 88.482 +que Mercurial los principios de su diseño fueron influenciados por 88.483 +Monotone. 88.484 + 88.485 +Git tiene un conjunto de órdenes muy grande; en la versión~1.5.0 88.486 +ofrece~139 órdenes individuales. Tiene cierta reputación de ser 88.487 +difícil de aprender. Comparado con Git, Mercurial tiene un fuerte 88.488 +enfoque hacia la facilidad. 88.489 + 88.490 +En términos de rendimiento, Git es extremadamente rápido. En muchos 88.491 +casos, es más rápido que Mercurial, por lo menos en Linux, mientras 88.492 +que Mercurial se comporta mejor en otras operaciones. De todas 88.493 +maneras en Windows, el desempeño y el nivel general de soporte que 88.494 +ofrece Git, al momento de la escritura, está bastante atrás de 88.495 +Mercurial. 88.496 + 88.497 +Mientras que el repositorio de Mercurial no requiere mantenimiento, el 88.498 +repositorio de Git requiere frecuentes ``reempaquetados'' de sus metadatos. 88.499 +Sin estos, el desempeño se degrada y el uso de espacio crece rápidamente. Un 88.500 +servidor que contenga repositorios de Git que no sean reempacados 88.501 +rigurosa y frecuentemente requerirá trabajo intenso de disco durante 88.502 +las copias de seguridad, y ha habido situaciones en copias de 88.503 +seguridad diaria que toman más de~24 horas como resultado. Un 88.504 +repositorio recién reempacado de Git es un poco más pequeño que un 88.505 +repositorio de Mercurial, pero un repositorio sin reempacar es varios 88.506 +órdenes de magnitud más grande. 88.507 + 88.508 +El corazón de Git está escrito en C. Muchas órdenes de Git están 88.509 +implementadas como guiones de línea de comandos o de Perl y la calidad de esos 88.510 +guiones varía ampliamente. He encontrado muchas situaciones en las 88.511 +cuales los guiones no tuvieron en cuenta la presencia de errores que 88.512 +podrían haber sido fatales. 88.513 + 88.514 +Mercurial puede importar el historial de revisiones de un repositorio 88.515 +de Git. 88.516 + 88.517 +\subsection{CVS} 88.518 + 88.519 +CVS es probablemente la herramienta de control de revisiones más 88.520 +ampliamente usada en el planeta. Debido a su edad y su poca pulcritud 88.521 +interna, ha sido ligeramente mantenida en muchos años. 88.522 + 88.523 +Tiene una arquitectura centralizada cliente/servidor. No agrupa 88.524 +cambios relacionados en consignaciones atómicas, pemitiendo que con 88.525 +facilidad la gente ``rompa la construcción'': una persona puede 88.526 +consignar exitósamente parte del cambio y estar bloqueada por la 88.527 +necesidad de una mezcla, forzando a otras personas a ver solamente una 88.528 +porción del trabajo que estaban buscando hacer. Esto afecta también 88.529 +la forma como usted trabaja con el historial del proyecto. Si quiere 88.530 +ver todas las modificaciones que alguien hizo como parte de una tarea, 88.531 +necesitará inspeccionar manualmente las descripciones y las marcas de 88.532 +tiempo de cambio de cada fichero involucrado (esto, si usted saber 88.533 +cuáles eran tales ficheros). 88.534 + 88.535 +CVS tiene una noción confusa de etiquetas y ramas que yo no trataría 88.536 +incluso de describir. No soporta renombramiento de ficheros o 88.537 +directorios adecuadamente, facilitando el corromper un 88.538 +repositorio. Casi no tiene chequeo de consistencia interna, por lo 88.539 +tanto es casi imposible identificar por que o cómo se corrompió un 88.540 +repositorio. Yo no recomendaría un repositorio de CVS para proyecto 88.541 +alguno, ni existente ni nuevo. 88.542 + 88.543 +Mercurial puede importar el historial de revisiones de CVS. De todas 88.544 +maneras hay ciertas precauciones que aplican; las cuales también son 88.545 +necesarias para cualquier herramienta importadora de historial de 88.546 +CVS. Debido a la falta de atomicidad de cambios y el no versionamiento 88.547 +de la jerarquía del sistema de ficheros, es imposible reconstruir 88.548 +completamente el historial de CVS con precisión; hay cierto trabajo de 88.549 +conjetura involucrado y los renombramientos tampoco se 88.550 +mostrarán. Debido a que gran parte de la administración avanzada de 88.551 +CVS tiene que hacerse manualmente y por lo tanto es proclive al error, 88.552 +es común que los importadores de CVS encuentren muchos problemas con 88.553 +repositorios corruptos (marcas de tiempo totalmente desubicadas y 88.554 +ficheros que han permanecido con candados por más de una década son 88.555 +dos de los problemas menos interesantes de los que puedo retomar de mi 88.556 +experiencia personal). 88.557 + 88.558 +Mercurial puede importar el historial de revisiones de un repositorio 88.559 +CVS. 88.560 + 88.561 +\subsection{Herramientas comerciales} 88.562 + 88.563 +Perforce tiene una arquitectura centralizada cliente/servidor sin 88.564 +almacenamiento de dato alguno de caché en el lado del cliente. A diferencia de 88.565 +las herramientas modernas de control de revisiones, Perforce requiere 88.566 +que un usuario ejecute un comando para informar al servidor acerca de 88.567 +todo fichero que se vaya a editar. 88.568 + 88.569 +El rendimiento de Perforce es muy bueno para equipos pequeños, pero se 88.570 +degrada rápidamente cuando el número de usuarios va más allá de pocas 88.571 +docenas. Instalaciones modestamente grandes de Perforce requiere la 88.572 +organización de proxies para soportar la carga que sus usuarios generan. 88.573 + 88.574 +\subsection{Elegir una herramienta de control de revisiones} 88.575 + 88.576 +Con la excepción de CVS, toda las herramientas que se han listado 88.577 +anteriormente tienen fortalezas únicas que las hacen valiosas de acuerdo al 88.578 +tipo de trabajo. No hay una única herramienta de control de revisiones 88.579 +que sea la mejor en todas las situaciones. 88.580 + 88.581 +Por ejemplo, Subversion es una buena elección para trabajar con 88.582 +edición frecuente de ficheros binarios, debido a su naturaleza 88.583 +centralizada y soporte para poner candados a ficheros. 88.584 + 88.585 +Personalmente encuentro las propiedades de simplicidad, desempeño, y 88.586 +buen soporte de fusiones de Mercurial una combinación llamativa que ha 88.587 +dado buenos frutos por varios años. 88.588 + 88.589 + 88.590 +\section{Migrar de otra herramienta hacia Mercurial} 88.591 + 88.592 +Mercurial viene con una extensión llamada \hgext{convert}, que puede 88.593 +importar historiales de revisiones de forma incremental desde varias 88.594 +herramientas de control de revisiones. Por ``incremental'', quiero 88.595 +decir que puede migrar toda el historial de un proyecto en una primera 88.596 +instancia y después volver a ejecutar la migración posteriormente para 88.597 +obtener los nuevos cambios que han sucedido después de la migración 88.598 +inicial. 88.599 + 88.600 +A continuación presentamos las herramientas de revisiones que soporta 88.601 +el comando \hgext{convert}: 88.602 +\begin{itemize} 88.603 +\item Subversion 88.604 +\item CVS 88.605 +\item Git 88.606 +\item Darcs 88.607 +\end{itemize} 88.608 + 88.609 +Adicionalmente, \hgext{convert} puede exportar cambios de Mercurial 88.610 +hacia Subversion. Lo que hace posible probar Subversion y Mercurial 88.611 +en paralelo antes de lanzarse a un migración total, sin arriesgarse a 88.612 +perder trabajo alguno. 88.613 + 88.614 +El comando \hgxcmd{conver}{convert} es sencillo de usar. Basta con 88.615 +apuntarlo hacia la ruta o el URL del repositorio fuente, opcionalmente 88.616 +darle el nombre del nombre del repositorio destino y comenzará a hacer 88.617 +su trabajo. Después de la conversión inicial, basta con invocar de 88.618 +nuevo el comando para importar cambios nuevos. 88.619 + 88.620 + 88.621 +%%% Local Variables: 88.622 +%%% mode: latex 88.623 +%%% TeX-master: "00book" 88.624 +%%% End:
89.1 Binary file es/kdiff3.png has changed
90.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 90.2 +++ b/es/license.tex Thu Jan 29 22:00:07 2009 -0800 90.3 @@ -0,0 +1,142 @@ 90.4 +\chapter{Licencia de Publicación Abierta} 90.5 +\label{cha:opl} 90.6 + 90.7 +Versión 1.0, 8 Junio de 1999 90.8 + 90.9 +\section{Requerimientos en versiones modificadas y no modificadas} 90.10 + 90.11 +Los trabajos bajo Publicación Abierta pueden reproducirse y 90.12 +distribuirse enteros o en porciones, en cualquier medio físico o 90.13 +electrónico, siempre y cuando se respeten los términos de esta 90.14 +licencia, y se incorpore esta licencia o su referencia (con cualquiera 90.15 +de las opciones elegidas por el autor y el editor) en la reproducción. 90.16 + 90.17 +A continuación mostramos la forma correcta de incorporar por referencia: 90.18 + 90.19 +\begin{quote} 90.20 + Copyright (c) \emph{año} por \emph{nombre del autor o designado}. 90.21 + Este material puede distribuirse solamente bajo los términos y 90.22 + condiciones especificados por la Licencia de Publicación Abierta, 90.23 + v\emph{x.y} o posterior (la última versión disponible está en 90.24 + \url{http://www.opencontent.org/openpub/}). 90.25 +\end{quote} 90.26 + 90.27 +La referencia debe estar seguida inmediatamente por cualquier opción 90.28 +elegida por el(os) autor(es) y/o editor(es) del documento (consulte la 90.29 +sección~\ref{sec:opl:options}). 90.30 + 90.31 +Se permite la redistribución comercial de los materiales sujetos a la 90.32 +Publicación Abierta. 90.33 + 90.34 +Cualquier publicación en forma estándar de libro (papel) requerirá 90.35 +citar al editor y autor original. Los nombres del editor y el autor 90.36 +aparecerán en todas las superficies externas del libro. En todas las 90.37 +superficies externas el nombre del editor deberá aparecer en tamaño de 90.38 +la misma medida que el título del trabajo y será citado como poseedor 90.39 +con respecto al título. 90.40 + 90.41 +\section{Derechos de reproducción} 90.42 + 90.43 +El derecho de reproducción de cada Publicación Abierta pertenece 90.44 +al(os) autor(es) o designados. 90.45 + 90.46 +\section{Alcance de la licencia} 90.47 + 90.48 +Los términos de licencia dsecritos aplican a todos los trabajos bajo 90.49 +licencia de publicación abierta a menos que se indique de otra forma 90.50 +en este documento. 90.51 + 90.52 +La simple agregación de trabajos de Publicación Abierta o una porción 90.53 +de trabajos de Publicación Abierta con otros trabajos o programas en 90.54 +el mismo medio no causarán que esta licencia se aplique a los otros 90.55 +trabajos. Los agregados deberán contener una nota que especifique la 90.56 +inclusión de matrial de Publicación Abierta y una nota de derechos de 90.57 +reproducción acorde. 90.58 + 90.59 +\textbf{Separabilidad}. Si cualquier porción de esta licencia no es 90.60 +aplicable en alguna jurisdicción, las porciones restantes se 90.61 +mantienen. 90.62 + 90.63 +\textbf{Sin garantía}. Los trabajos de Publicación Abierta se 90.64 +licencian y ofrecen ``como están'' sin garantía de ninguna clase, 90.65 +expresa o implícita, incluyendo, pero no limitados a las garantías de 90.66 +mercabilidad y adaptabilidad para un propósito particular o garantía 90.67 +de no infracción. 90.68 + 90.69 +\section{Requerimientos sobre trabajos modificados} 90.70 + 90.71 +Todas las versiones modificadas de documentos cubiertos por esta 90.72 +licencia, incluyendo traducciones, antologías, compilaciones y 90.73 +documentos parciales, deben seguir estos requerimientos: 90.74 + 90.75 +\begin{enumerate} 90.76 +\item La versión modificada debe estar etiquetada como tal. 90.77 +\item La persona que hace la modificación debe estar identificada y la 90.78 + modificación con fecha. 90.79 +\item El dar crédito al autor original y al editor si se requiere de 90.80 + acuerdo a las prácticas académicas de citas. 90.81 +\item Debe identificarse el lugar del documento original sin 90.82 + modificación. 90.83 +\item No puede usarse el(os) nombre(s) del autor (de los autores) para 90.84 + implicar relación alguna con el documento resultante sin el permiso 90.85 + explícito del autor (o de los autores). 90.86 +\end{enumerate} 90.87 + 90.88 +\section{Recomendaciones de buenas prácticas} 90.89 + 90.90 +Adicional a los requerimientos de esta licencia, se solicita a los 90.91 +redistribuidores y se recomienda en gran medida que: 90.92 + 90.93 +\begin{enumerate} 90.94 +\item Si está distribuyendo trabajaos de Publicación Abierta en copia 90.95 + dura o CD-ROM, envíe una notificación por correo a los autores 90.96 + acerca de su intención de redistribuir por lo menos con treinta días 90.97 + antes de que su manuscrito o el medio se congelen, para permitir a 90.98 + los autores tiempo para proveer documentos actualizados. Esta 90.99 + notificación debería describir las modificaciones, en caso de que 90.100 + haya, al documento. 90.101 +\item Todas las modificaciones sustanciales (incluyendo eliminaciones) 90.102 + deben estar marcadas claramente en el documento o si no descritas en 90.103 + un adjunto del documento. 90.104 +\item Finalmente, aunque no es obligatorio bajo esta licencia, se 90.105 + considera de buenos modales enviar una copia gratis de cualquier 90.106 + expresión en copia dura o CD-ROM de un trabajo licenciado con 90.107 + Publicación Abierta a el(os) autor(es). 90.108 +\end{enumerate} 90.109 + 90.110 +\section{Opciones de licencia} 90.111 +\label{sec:opl:options} 90.112 + 90.113 +El(os) autor(es) y/o editor de un documento licenciado con Publicación 90.114 +Abierta pueden elegir ciertas opciones añadiendo información a la 90.115 +referencia o a la copia de la licencia. Estas opciones se consideran 90.116 +parte de la instancia de la licencia y deben incluirse con la 90.117 +licencia (o su incorporación con referencia) en trabajos derivados. 90.118 + 90.119 +\begin{enumerate}[A] 90.120 +\item Prohibir la distribución de versiones substancialmente 90.121 + modificadas sin el permiso explícito del(os) autor(es). Se definen 90.122 + ``modificaciones substanciales'' como cambios en el contenido 90.123 + semántico del documento, y se excluyen simples cambios en el formato 90.124 + o correcciones tipográficas. 90.125 + 90.126 + Para lograr esto, añada la frase ``Se prohibe la distribución de 90.127 + versiones substancialmente modificadas de este documento sin el 90.128 + permiso explícito del dueño de los derechos de reproducción.'' a la 90.129 + referencia de la licencia o a la copia. 90.130 + 90.131 +\item Está prohibido prohibir cualquier publicación de este trabajo o 90.132 + derivados como un todo o una parte en libros estándar (de papel) con 90.133 + propósitos comerciales a menos que se obtenga un permiso previo del 90.134 + dueño de los derechos de reproducción. 90.135 + 90.136 + Para lograrlo, añada la frase ``La distribución del trabajo o 90.137 + derivados en cualquier libro estándar (papel) se prohibe a menos que 90.138 + se obtenga un permiso previo del dueño de los derechos de 90.139 + reproducción.'' a la referencia de la licencia o la copia. 90.140 +\end{enumerate} 90.141 + 90.142 +%%% Local Variables: 90.143 +%%% mode: latex 90.144 +%%% TeX-master: "00book" 90.145 +%%% End:
91.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 91.2 +++ b/es/metadata.svg Thu Jan 29 22:00:07 2009 -0800 91.3 @@ -0,0 +1,337 @@ 91.4 +<?xml version="1.0" encoding="UTF-8" standalone="no"?> 91.5 +<!-- Created with Inkscape (http://www.inkscape.org/) --> 91.6 +<svg 91.7 + xmlns:dc="http://purl.org/dc/elements/1.1/" 91.8 + xmlns:cc="http://creativecommons.org/ns#" 91.9 + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 91.10 + xmlns:svg="http://www.w3.org/2000/svg" 91.11 + xmlns="http://www.w3.org/2000/svg" 91.12 + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" 91.13 + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" 91.14 + width="744.09448819" 91.15 + height="1052.3622047" 91.16 + id="svg2" 91.17 + sodipodi:version="0.32" 91.18 + inkscape:version="0.46" 91.19 + sodipodi:docname="metadata.svg" 91.20 + sodipodi:docbase="/home/bos/hg/hgbook/en" 91.21 + inkscape:output_extension="org.inkscape.output.svg.inkscape"> 91.22 + <defs 91.23 + id="defs4"> 91.24 + <inkscape:perspective 91.25 + sodipodi:type="inkscape:persp3d" 91.26 + inkscape:vp_x="0 : 526.18109 : 1" 91.27 + inkscape:vp_y="0 : 1000 : 0" 91.28 + inkscape:vp_z="744.09448 : 526.18109 : 1" 91.29 + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" 91.30 + id="perspective2479" /> 91.31 + <marker 91.32 + inkscape:stockid="Arrow1Mend" 91.33 + orient="auto" 91.34 + refY="0.0" 91.35 + refX="0.0" 91.36 + id="Arrow1Mend" 91.37 + style="overflow:visible;"> 91.38 + <path 91.39 + id="path2944" 91.40 + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " 91.41 + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;" 91.42 + transform="scale(0.4) rotate(180) translate(10,0)" /> 91.43 + </marker> 91.44 + </defs> 91.45 + <sodipodi:namedview 91.46 + id="base" 91.47 + pagecolor="#ffffff" 91.48 + bordercolor="#666666" 91.49 + borderopacity="1.0" 91.50 + gridtolerance="10000" 91.51 + guidetolerance="10" 91.52 + objecttolerance="10" 91.53 + inkscape:pageopacity="0.0" 91.54 + inkscape:pageshadow="2" 91.55 + inkscape:zoom="0.98994949" 91.56 + inkscape:cx="232.14286" 91.57 + inkscape:cy="519.03485" 91.58 + inkscape:document-units="px" 91.59 + inkscape:current-layer="layer1" 91.60 + inkscape:window-width="906" 91.61 + inkscape:window-height="659" 91.62 + inkscape:window-x="181" 91.63 + inkscape:window-y="58" 91.64 + showgrid="false" /> 91.65 + <metadata 91.66 + id="metadata7"> 91.67 + <rdf:RDF> 91.68 + <cc:Work 91.69 + rdf:about=""> 91.70 + <dc:format>image/svg+xml</dc:format> 91.71 + <dc:type 91.72 + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> 91.73 + </cc:Work> 91.74 + </rdf:RDF> 91.75 + </metadata> 91.76 + <g 91.77 + inkscape:label="Layer 1" 91.78 + inkscape:groupmode="layer" 91.79 + id="layer1"> 91.80 + <path 91.81 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#a7a7a7;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4.5, 1.5;stroke-dashoffset:0;stroke-opacity:1;display:inline" 91.82 + d="M 326.94646,467.18359 L 326.94646,510.98123" 91.83 + id="path1910" 91.84 + inkscape:connector-type="polyline" 91.85 + inkscape:connection-end="#rect2962" 91.86 + inkscape:connection-start="#rect2764" /> 91.87 + <path 91.88 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#a7a7a7;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4.5, 1.5;stroke-dashoffset:0;stroke-opacity:1;display:inline" 91.89 + d="M 326.94646,531.98123 L 326.94646,591.77887" 91.90 + id="path1912" 91.91 + inkscape:connector-type="polyline" 91.92 + inkscape:connection-start="#rect2962" 91.93 + inkscape:connection-end="#rect3000" /> 91.94 + <path 91.95 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#a7a7a7;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4.5, 1.5;stroke-dashoffset:0;stroke-opacity:1;display:inline" 91.96 + d="M 316.1622,531.98123 L 192.30212,652.57648" 91.97 + id="path1916" 91.98 + inkscape:connector-type="polyline" 91.99 + inkscape:connection-end="#rect3038" 91.100 + inkscape:connection-start="#rect2962" /> 91.101 + <path 91.102 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#484848;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4.5, 1.5;stroke-dashoffset:0;stroke-opacity:1" 91.103 + d="M 254.23217,467.18359 L 254.23216,510.98123" 91.104 + id="path3088" 91.105 + inkscape:connector-type="polyline" 91.106 + inkscape:connection-start="#rect1872" 91.107 + inkscape:connection-end="#rect2960" /> 91.108 + <path 91.109 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#484848;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4.5, 1.5;stroke-dashoffset:0;stroke-opacity:1" 91.110 + d="M 254.23215,531.98123 L 254.23215,591.77887" 91.111 + id="path3090" 91.112 + inkscape:connector-type="polyline" 91.113 + inkscape:connection-start="#rect2960" 91.114 + inkscape:connection-end="#rect2998" /> 91.115 + <path 91.116 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#484848;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4.5, 1.5;stroke-dashoffset:0;stroke-opacity:1" 91.117 + d="M 248.84002,531.98123 L 186.90999,652.57648" 91.118 + id="path3092" 91.119 + inkscape:connector-type="polyline" 91.120 + inkscape:connection-start="#rect2960" 91.121 + inkscape:connection-end="#rect3038" /> 91.122 + <rect 91.123 + style="fill:#7b7df5;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 91.124 + id="rect1872" 91.125 + width="51.42857" 91.126 + height="20" 91.127 + x="228.51788" 91.128 + y="446.68359" /> 91.129 + <rect 91.130 + style="fill:#cacbfb;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 91.131 + id="rect2764" 91.132 + width="51.42857" 91.133 + height="20" 91.134 + x="301.23218" 91.135 + y="446.68359" /> 91.136 + <rect 91.137 + style="fill:#cacbfb;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 91.138 + id="rect2766" 91.139 + width="51.42857" 91.140 + height="20" 91.141 + x="155.80359" 91.142 + y="446.68359" /> 91.143 + <rect 91.144 + style="fill:#cacbfb;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 91.145 + id="rect2768" 91.146 + width="51.42857" 91.147 + height="20" 91.148 + x="83.089294" 91.149 + y="446.68359" /> 91.150 + <path 91.151 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" 91.152 + d="M 135.01786,456.68359 L 155.30359,456.68359" 91.153 + id="path2770" 91.154 + inkscape:connector-type="polyline" 91.155 + inkscape:connection-start="#rect2768" 91.156 + inkscape:connection-end="#rect2766" /> 91.157 + <path 91.158 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" 91.159 + d="M 207.73216,456.68359 L 228.01788,456.68359" 91.160 + id="path2772" 91.161 + inkscape:connector-type="polyline" 91.162 + inkscape:connection-start="#rect2766" 91.163 + inkscape:connection-end="#rect1872" /> 91.164 + <path 91.165 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" 91.166 + d="M 280.44645,456.68359 L 300.73218,456.68359" 91.167 + id="path2774" 91.168 + inkscape:connector-type="polyline" 91.169 + inkscape:connection-start="#rect1872" 91.170 + inkscape:connection-end="#rect2764" /> 91.171 + <path 91.172 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:3, 3;stroke-dashoffset:0;stroke-opacity:1" 91.173 + d="M 62.303571,456.68359 L 82.589294,456.68359" 91.174 + id="path2778" 91.175 + inkscape:connector-type="polyline" 91.176 + inkscape:connection-end="#rect2768" /> 91.177 + <rect 91.178 + style="fill:#84f57b;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 91.179 + id="rect2960" 91.180 + width="51.42857" 91.181 + height="20" 91.182 + x="228.51787" 91.183 + y="511.48123" /> 91.184 + <rect 91.185 + style="fill:#cefbca;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 91.186 + id="rect2962" 91.187 + width="51.42857" 91.188 + height="20" 91.189 + x="301.23218" 91.190 + y="511.48123" /> 91.191 + <rect 91.192 + style="fill:#cefbca;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 91.193 + id="rect2964" 91.194 + width="51.42857" 91.195 + height="20" 91.196 + x="155.80357" 91.197 + y="511.48123" /> 91.198 + <rect 91.199 + style="fill:#cefbca;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 91.200 + id="rect2966" 91.201 + width="51.42857" 91.202 + height="20" 91.203 + x="83.089287" 91.204 + y="511.48123" /> 91.205 + <path 91.206 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" 91.207 + d="M 135.01786,521.48121 L 155.30359,521.48121" 91.208 + id="path2968" 91.209 + inkscape:connector-type="polyline" /> 91.210 + <path 91.211 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" 91.212 + d="M 207.73216,521.48121 L 228.01788,521.48121" 91.213 + id="path2970" 91.214 + inkscape:connector-type="polyline" /> 91.215 + <path 91.216 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" 91.217 + d="M 280.44645,521.48121 L 300.73218,521.48121" 91.218 + id="path2972" 91.219 + inkscape:connector-type="polyline" /> 91.220 + <path 91.221 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:3, 3;stroke-dashoffset:0;stroke-opacity:1" 91.222 + d="M 62.30358,521.48121 L 82.5893,521.48121" 91.223 + id="path2974" 91.224 + inkscape:connector-type="polyline" /> 91.225 + <rect 91.226 + style="fill:#f57b8f;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 91.227 + id="rect2998" 91.228 + width="51.42857" 91.229 + height="20" 91.230 + x="228.51787" 91.231 + y="592.27887" /> 91.232 + <rect 91.233 + style="fill:#fbcad2;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 91.234 + id="rect3000" 91.235 + width="51.42857" 91.236 + height="20" 91.237 + x="301.23218" 91.238 + y="592.27887" /> 91.239 + <rect 91.240 + style="fill:#fbcad2;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 91.241 + id="rect3002" 91.242 + width="51.42857" 91.243 + height="20" 91.244 + x="155.80357" 91.245 + y="592.27887" /> 91.246 + <rect 91.247 + style="fill:#fbcad2;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 91.248 + id="rect3004" 91.249 + width="51.42857" 91.250 + height="20" 91.251 + x="83.089287" 91.252 + y="592.27887" /> 91.253 + <path 91.254 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" 91.255 + d="M 135.01786,602.27884 L 155.30359,602.27884" 91.256 + id="path3006" 91.257 + inkscape:connector-type="polyline" /> 91.258 + <path 91.259 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" 91.260 + d="M 207.73216,602.27884 L 228.01788,602.27884" 91.261 + id="path3008" 91.262 + inkscape:connector-type="polyline" /> 91.263 + <path 91.264 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" 91.265 + d="M 280.44645,602.27884 L 300.73218,602.27884" 91.266 + id="path3010" 91.267 + inkscape:connector-type="polyline" /> 91.268 + <path 91.269 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:3, 3;stroke-dashoffset:0;stroke-opacity:1" 91.270 + d="M 62.30358,602.27884 L 82.5893,602.27884" 91.271 + id="path3012" 91.272 + inkscape:connector-type="polyline" /> 91.273 + <rect 91.274 + style="fill:#ffced6;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 91.275 + id="rect3034" 91.276 + width="51.42857" 91.277 + height="20" 91.278 + x="228.51787" 91.279 + y="653.07648" /> 91.280 + <rect 91.281 + style="fill:#f57b8f;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 91.282 + id="rect3038" 91.283 + width="51.42857" 91.284 + height="20" 91.285 + x="155.80357" 91.286 + y="653.07648" /> 91.287 + <rect 91.288 + style="fill:#fbcad2;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 91.289 + id="rect3040" 91.290 + width="51.42857" 91.291 + height="20" 91.292 + x="83.089287" 91.293 + y="653.07648" /> 91.294 + <path 91.295 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" 91.296 + d="M 135.01786,663.07646 L 155.30359,663.07646" 91.297 + id="path3042" 91.298 + inkscape:connector-type="polyline" /> 91.299 + <path 91.300 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" 91.301 + d="M 207.73216,663.07646 L 228.01788,663.07646" 91.302 + id="path3044" 91.303 + inkscape:connector-type="polyline" /> 91.304 + <path 91.305 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:3, 3;stroke-dashoffset:0;stroke-opacity:1" 91.306 + d="M 62.30358,663.07646 L 82.5893,663.07646" 91.307 + id="path3048" 91.308 + inkscape:connector-type="polyline" /> 91.309 + <text 91.310 + xml:space="preserve" 91.311 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 91.312 + x="82.072548" 91.313 + y="432.64789" 91.314 + id="text3094"><tspan 91.315 + sodipodi:role="line" 91.316 + id="tspan3096" 91.317 + x="82.072548" 91.318 + y="432.64789">Bitácora de cambios</tspan></text> 91.319 + <text 91.320 + xml:space="preserve" 91.321 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 91.322 + x="82.306923" 91.323 + y="498.97327" 91.324 + id="text3098"><tspan 91.325 + sodipodi:role="line" 91.326 + id="tspan3100" 91.327 + x="82.306923" 91.328 + y="498.97327">Manifiesto</tspan></text> 91.329 + <text 91.330 + xml:space="preserve" 91.331 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 91.332 + x="82.14286" 91.333 + y="580.08569" 91.334 + id="text3102"><tspan 91.335 + sodipodi:role="line" 91.336 + id="tspan3104" 91.337 + x="82.14286" 91.338 + y="580.08569">Bitácora de archivos</tspan></text> 91.339 + </g> 91.340 +</svg>
92.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 92.2 +++ b/es/mq-collab.tex Thu Jan 29 22:00:07 2009 -0800 92.3 @@ -0,0 +1,428 @@ 92.4 +\chapter{Usos avanzados de las Colas de Mercurial} 92.5 +\label{chap:mq-collab} 92.6 + 92.7 +Auunque es fácil aprender los usos más directos de las Colas de 92.8 +Mercurial, tener algo de disciplina junto con algunas de las 92.9 +capacidadees menos usadas de MQ hace posible trabajar en entornos de 92.10 +desarrollo complejos. 92.11 + 92.12 +En este capítulo, usaré como ejemplo una técnica que he usado para 92.13 +administrar el desarrollo de un controlador de dispositivo Infiniband 92.14 +para el kernel de Linux. El controlador en cuestión es grande 92.15 +(al menos en lo que se refiere a controladores), con 25,000 líneas de 92.16 +código esparcidas en 35 ficheros fuente. Es mantenido por un equipo 92.17 +pequeño de desarrolladores. 92.18 + 92.19 +Aunque mucho del material en este capítulo es específico de Linux, los 92.20 +mismos principios aplican a cualquier base de código de la que usted 92.21 +no sea el propietario principal, y sobre la que usted necesita hacer 92.22 +un montón de desarrollo. 92.23 + 92.24 +\section{El problema de múltiples objetivos} 92.25 + 92.26 +El kernel de Linux cambia con rapidez, y nunca ha sido estable 92.27 +internamente; los desarrolladores hacen cambios drásticos entre 92.28 +%TODO no encontré una traducción adecuada para "release". Por eso el 92.29 +%cambio 92.30 +versiones frecuentemente. Esto significa que una versión del 92.31 +controlador que funciona bien con una versión particular del kernel ni 92.32 +siquiera \emph{compilará} correctamente contra, típicamente, cualquier 92.33 +otra versión. 92.34 + 92.35 +Para mantener un controlador, debemos tener en cuenta una buena 92.36 +cantidad de versiones de Linux en mente. 92.37 +\begin{itemize} 92.38 +\item Un objetivo es el árbol de desarrollo principal del kernel de 92.39 + Linux. En este caso el mantenimiento del código es compartido 92.40 + parcialmente por otros desarrolladores en la comunidad del kernel, 92.41 + %TODO drive-by. 92.42 + quienes hacen modificaciones ``de-afán'' al controlador a medida que 92.43 + desarrollan y refinan subsistemas en el kernel. 92.44 + %TODO backport 92.45 +\item También mantenemos algunos ``backports'' para versiones antiguas 92.46 + del kernel de Linux, para dar soporte a las necesidades de los 92.47 + clientes que están corriendo versiones antiguas de Linux que no 92.48 + incorporan nuestros controladores. (Hacer el \emph{backport} de un 92.49 + pedazo de código es modificarlo para que trabaje en una versión 92.50 + de su entorno objetivo anterior a aquella para la cual fue escrito.) 92.51 +\item Finalmente, nosotros liberamos nuestro software de acuerdo a un 92.52 + cronograma que no necesariamente está alineado con el que usan los 92.53 + distribuidores de Linux y los desarrolladores del kernel, así que 92.54 + podemos entregar nuevas características a los clientes sin forzarlos 92.55 + a actualizar kernels completos o distribuciones. 92.56 +\end{itemize} 92.57 + 92.58 +\subsection{Aproximaciones tentadoras que no funcionan adecuadamente} 92.59 + 92.60 +Hay dos maneras estándar de mantener una porción de software que debe 92.61 +funcionar en muchos entornos diferentes. 92.62 + 92.63 +La primera es mantener varias ramas, cada una pensada para un único 92.64 +entorno. El problema de esta aproximación es que usted debe tener una 92.65 +disciplina férrea con el flujo de cambios entre repositorios. Una 92.66 +nueva característica o un arreglo de fallo deben empezar su vida en un 92.67 +repositorio ``prístino'', y luego propagarse a cada repositorio de 92.68 +backport. Los cambios para backports están más limitados respecto a 92.69 +las ramas a las que deberían propagarse; un cambio para backport que 92.70 +es aplicado a una rama en la que no corresponde probablemente hará que 92.71 +el controlador no compile. 92.72 + 92.73 +La segunda es mantener un único árbol de código fuente lleno de 92.74 +declaraciones que activen o desactiven secciones de código dependiendo 92.75 +del entorno objetivo. Ya que estos ``ifdefs'' no están permitidos en 92.76 +el árbol del kernel de Linux, debe seguirse algún proceso manual o 92.77 +automático para eliminarlos y producir un árbol limpio. Una base de 92.78 +código mantenida de esta manera se convierte rápidamente en un nido de 92.79 +ratas de bloques condicionales que son difíciles de entender y 92.80 +mantener. 92.81 + 92.82 +%TODO canónica? 92.83 +Ninguno de estos enfoques es adecuado para situaciones en las que 92.84 +usted no es ``dueño'' de la copia canónica de un árbol de fuentes. En 92.85 +el caso de un controlador de Linux que es distribuido con el kernel 92.86 +estándar, el árbol de Linux contiene la copia del código que será 92.87 +considerada por el mundo como la canónica. La versión oficial de 92.88 +``mi'' controlador puede ser modificada por gente que no conozco, sin 92.89 +que yo siquiera me entere de ello hasta después de que los cambios 92.90 +aparecen en el árbol de Linus. 92.91 + 92.92 +Estos enfoques tienen la debilidad adicional de dificultar la 92.93 +%TODO upstream. no no es río arriba 92.94 +generación de parches bien formados para enviarlos a la versión 92.95 +oficial. 92.96 + 92.97 +En principio, las Colas de Mercurial parecen ser un buen candidato 92.98 +para administrar un escenario de desarrollo como el de arriba. Aunque 92.99 +este es de hecho el caso, MQ tiene unas cuantas características 92.100 +adicionales que hacen el trabajo más agradable. 92.101 + 92.102 +\section{Aplicar parches condicionalmente mediante guardias} 92.103 + 92.104 +Tal vez la mejor manera de conservar la cordura con tantos entornos 92.105 +objetivo es poder escoger parches específicos para aplicar para cada 92.106 +situación. MQ provee una característica llamada ``guardias'' 92.107 +(que se origina del comando \texttt{guards} de Quilt) que hace 92.108 +precisamente ésto. Para empezar, creemos un repositorio sencillo para 92.109 +experimentar. 92.110 +\interaction{mq.guards.init} 92.111 +Esto nos brinda un pequeño repositorio que contiene dos parches que no 92.112 +tienen ninguna dependencia respecto al otro, porque tocan ficheros 92.113 +diferentes. 92.114 + 92.115 +La idea detrás de la aplicación condicional es que usted puede 92.116 +``etiquetar'' un parche con un \emph{guardia}, que simplemente es una 92.117 +cadena de texto de su elección, y luego decirle a MQ que seleccione 92.118 +guardias específicos para usar cuando aplique parches. MQ entonces 92.119 +aplicará, u omitirá, un parche vigilado, dependiendo de los guardias 92.120 +que usted haya seleccionado. 92.121 + 92.122 +Un parche puede tener una cantidad arbitraria de guardias; cada uno es 92.123 +\emph{positivo} (``aplique el parche si este guardia es 92.124 +seleccionado'') o \emph{negativo} (``omita este parche si este guardia 92.125 +es seleccionado''). Un parche sin guardias siempre es aplicado. 92.126 + 92.127 +\section{Controlar los guardias de un parche} 92.128 + 92.129 +%TODO tal vez no decir determinar, sino definir? 92.130 +El comando \hgxcmd{mq}{qguard} le permite determinar qué guardias 92.131 +deben aplicarse a un parche, o mostrar los guardias que están en 92.132 +efecto. Sin ningún argumento, el comando muestra los guardias del 92.133 +parche actual de la parte más alta de la pila. 92.134 +\interaction{mq.guards.qguard} 92.135 +Para poner un guardia positivo en un parche, prefije el nombre del 92.136 +guardia con un ``\texttt{+}''. 92.137 +\interaction{mq.guards.qguard.pos} 92.138 +Para poner un guardia negativo en un parche, prefije el nombre del 92.139 +guardia con un ``\texttt{-}''. 92.140 +\interaction{mq.guards.qguard.neg} 92.141 + 92.142 +\begin{note} 92.143 + El comando \hgxcmd{mq}{qguard} \emph{pone} los guardias en un 92.144 + parche; no los \emph{modifica}. Esto significa que si usted ejecuta 92.145 + \hgcmdargs{qguard}{+a +b} sobre un parche, y luego 92.146 + \hgcmdargs{qguard}{+c} en el mismo parche, el único guardia sobre el 92.147 + parche después del comando será \texttt{+c}. 92.148 +\end{note} 92.149 + 92.150 +Mercurial almacena los guardias en el fichero \sfilename{series}; la 92.151 +forma en que son almacenados es fácil tanto de entender como de editar 92.152 +a mano. (En otras palabras, usted no tiene que usar el comando 92.153 +\hgxcmd{mq}{qguard} si no lo desea; está bien simplemente editar el 92.154 +fichero \sfilename{series}) 92.155 +\interaction{mq.guards.series} 92.156 + 92.157 +\section{Selecccionar los guardias a usar} 92.158 + 92.159 +%TODO tal vez no decir determinar, sino definir? 92.160 +El comando \hgxcmd{mq}{qselect} determina qué guardias están activos 92.161 +en cualquier momento. El efecto de esto es determinar qué parches 92.162 +aplicará MQ la próxima vez que usted ejecute \hgxcmd{mq}{qpush}. No 92.163 +tiene ningún otro efecto; en particular, no hace nada a los parches 92.164 +que ya han sido aplicados. 92.165 + 92.166 +Sin argumentos, el comando \hgxcmd{mq}{qselect} lista los guardias en 92.167 +efecto actualmente, uno por cada línea de salida. Cada argumento es 92.168 +tratado como el nombre de un guardia a aplicar. 92.169 +\interaction{mq.guards.qselect.foo} 92.170 +Si está interesado, los guardias seleccionados actualmente están 92.171 +almacenados en el fichero \sfilename{guards}. 92.172 +\interaction{mq.guards.qselect.cat} 92.173 +Podemos ver el efecto que tienen los guardias seleccionados cuando 92.174 +ejecutamos \hgxcmd{mq}{qpush}. 92.175 +\interaction{mq.guards.qselect.qpush} 92.176 + 92.177 +Un guardia no puede empezar con un caracter ``\texttt{+}'' o 92.178 +``\texttt{-}''. El nombre del guardia no debe contener espacios en 92.179 +blanco, pero muchos otros caracteres son aceptables. Si usted trata de 92.180 +usar un guardia con un nombre inválido, MQ se quejará: 92.181 +\interaction{mq.guards.qselect.error} 92.182 +Cambiar los guardias seleccionados cambia los parches que son 92.183 +aplicados. 92.184 +\interaction{mq.guards.qselect.quux} 92.185 +Usted puede ver en el ejemplo de abajo que los guardias negativos 92.186 +tienen precedencia sobre los guardias positivos. 92.187 +\interaction{mq.guards.qselect.foobar} 92.188 + 92.189 +\section{Reglas de MQ para aplicar parches} 92.190 + 92.191 +Las reglas que MQ usa para decidir si debe aplicar un parche son las 92.192 +siguientes. 92.193 +\begin{itemize} 92.194 +\item Un parche sin guardias es aplicado siempre. 92.195 +\item Si el parche tiene algún guardia negativo que corresponda con 92.196 + cualquiera de los guardias seleccionados, se salta el parche. 92.197 +\item Si el parche tiene algún guardia positivo que corresponda con 92.198 + cualquiera de los guardias seleccionados, se aplica el parche. 92.199 +\item Si el parche tiene guardias positivos o negativos, pero ninguno 92.200 + corresponde con cualquiera de los guardias seleccionados, se salta 92.201 + el parche. 92.202 +\end{itemize} 92.203 + 92.204 +\section{Podar el entorno de trabajo} 92.205 + 92.206 +En el trabajo del controlador de dispositivo que mencioné 92.207 +anteriormente, yo no aplico los parches a un árbol normal del kernel 92.208 +de Linux. En cambio, uso un repositorio que sólo contiene una 92.209 +instantánea de los ficheros fuente y de cabecera que son relevantes 92.210 +para el desarrollo de Infiniband. Este repositorio tiene un~1\% del 92.211 +tamaño del repositorio del kernel, por lo que es más fácil trabajar 92.212 +con él. 92.213 + 92.214 +Luego escojo una versión ``base'' sobre la cual son aplicados los 92.215 +parches. Es una instantánea del árbol del kernel de Linux en una 92.216 +revisión de mi elección. Cuando tomo la instantánea, almaceno el ID de 92.217 +conjunto de cambios en el mensaje de consignación. Ya que la 92.218 +instantánea preserva la ``forma'' y el contenido de las partes 92.219 +relevantes del árbol del kernel, puedo aplicar mis parches sobre mi 92.220 +pequeño repositorio o sobre un árbol normal del kernel. 92.221 + 92.222 +Normalmente, el árbol base sobre el que se aplican los parches debería 92.223 +ser una instantánea de un árbol de desarrollo muy reciente. Esto 92.224 +facilita mucho el desarrollo de parches que puedan ser enviados al 92.225 +árbol oficial con pocas o ninguna modificación. 92.226 + 92.227 +\section{Dividir el fichero \sfilename{series}} 92.228 + 92.229 +Yo categorizo los parches en el fichero \sfilename{series} en una 92.230 +serie de grupos lógicos. Cada sección de parches similares empieza con 92.231 +un bloque de comentarios que describen el propósito de los parches que 92.232 +le siguen. 92.233 + 92.234 +La secuencia de grupos de parches que mantengo se muestra a 92.235 +continuación. El orden de los grupos es importante; explicaré porqué 92.236 +luego de que presente los grupos. 92.237 +\begin{itemize} 92.238 +\item El grupo ``aceptado''. Son parches que el equipo de desarrollo 92.239 + ha enviado al mantenedor del subsistema Infiniband, y que él ha 92.240 + aceptado, pero que no están presentes en la instantánea en la cual 92.241 + está basada el repositorio pequeño. Estos son parches de 92.242 + ``sólo lectura'', presentes únicamente para transformar el árbol en 92.243 + un estado similar al del repositorio del mantenedor oficial. 92.244 +\item El grupo ``revisar''. Parches que yo he enviado, pero sobre los 92.245 + que que el mantenedor oficial ha solicitado modificaciones antes de 92.246 + aceptarlos. 92.247 +\item El grupo ``pendiente''. Parches que no he enviado al mantenedor 92.248 + oficial, pero que ya están terminados. Estos parches serán de 92.249 + ``sólo lectura'' por un buen tiempo. Si el mantenedor oficial los 92.250 + acepta cuando los envíe, los moveré al final del grupo ``aceptado''. 92.251 + Si él solicita que modificaciones en alguno de ellos, los moveré al 92.252 + principio del grupo ``revisar''. 92.253 +\item El grupo ``en proceso''. Parches que están siendo activamente 92.254 + desarrollados, y no deberían ser enviados a ninguna parte aún. 92.255 +\item El grupo ``backport''. Parches que adaptan el árbol de fuentes a 92.256 + versiones antiguas del árbol del kernel. 92.257 +\item El grupo ``no enviar''. Parches que por alguna razón nunca deben 92.258 + ser enviados al mantenedor oficial del kernel. Por ejemplo, alguno 92.259 + de esos parches podría cambiar las cadenas de identificación 92.260 + embebidas del controlador para hacer más fácil la distinción, en 92.261 + pruebas de campo, entre una versión del controlador de 92.262 + salida-del-árbol y una versión entregada por un vendedor de alguna 92.263 + distribución. 92.264 +\end{itemize} 92.265 + 92.266 +Ahora volvemos a las razones para ordenar los grupos de parches en 92.267 +esta manera. Quisiéramos que los parches del fondo de la pila sean tan 92.268 +estables como sea posible, para no tener que revisar parches más 92.269 +arriba debido a cambios de contexto. Poner los parches que nunca 92.270 +cambiarán en el primer lugar del fichero \sfilename{series} sirve a 92.271 +este propósito. 92.272 + 92.273 +También desearíamos que los parches que sabemos que debemos modificar 92.274 +sean aplicados sobre un árbol de fuentes que se parezca al oficial 92.275 +tanto como sea posible. Es por esto que mantenemos los parches 92.276 +aceptados disponibles por una buena cantidad de tiempo. 92.277 + 92.278 +Los parches ``backport'' y ``no enviar'' flotan al final del fichero 92.279 +\sfilename{series}. Los parches de backport deben ser aplicados encima 92.280 +de todos los otros parches, y los parches ``no enviar'' pueden 92.281 +perfectamente quedarse fuera del camino. 92.282 + 92.283 +\section{Mantener la serie de parches} 92.284 + 92.285 +En mi trabajo, uso varios guardias para controlar qué parches deben 92.286 +ser aplicados. 92.287 + 92.288 +\begin{itemize} 92.289 +\item Los parches ``aceptados'' son vigilados con 92.290 + \texttt{accepted}. Yo habilito este guardia la mayoría de las veces. 92.291 + Cuando aplico los parches sobre un árbol donde los parches ya están 92.292 + %TODO no será ``desactivar este guardia''? si sí, corregir versión 92.293 + %en inglés también 92.294 + presentes, puedo desactivar este parche, y los parches que lo siguen 92.295 + se aplicarán sin problemas. 92.296 +\item Los parches que están ``terminados'', pero no han sido enviados, 92.297 + no tienen guardias. Si estoy aplicando la pila de parches a una 92.298 + copia del árbol oficial, no necesito habilitar ningún guardia para 92.299 + obtener un árbol de fuentes razonablemente seguro. 92.300 +\item Los parches que necesitan revisión antes de ser reenviados 92.301 + tienen el guardia \texttt{rework}. 92.302 +\item Para aquellos parches que aún están bajo desarrollo, uso 92.303 + \texttt{devel}. 92.304 +\item Un parche de backport puede tener varios guardias, uno para cada 92.305 + versión del kernel a la que aplica. Por ejemplo, un parche que hace 92.306 + backport de un segmento de código a~2.6.9 tendrá un guardia~\texttt{2.6.9}. 92.307 +\end{itemize} 92.308 +La variedad de guardias me brinda una flexibilidad considerable para 92.309 +determinar qué tipo de árbol de fuentes acabaré por obtener. En la 92.310 +mayoría de las situaciones, la selección de guardias apropiados es 92.311 +automatizada durante el proceso de compilación, pero puedo ajustar 92.312 +manualmente los guardias a usar para circunstancias poco comunes. 92.313 + 92.314 +\subsection{El arte de escribir parches de backport} 92.315 + 92.316 +Al usar MQ, escribir un parche de backport es un proceso simple. Todo 92.317 +lo que dicho parche debe hacer es modificar una sección de código que 92.318 +usa una característica del kernel que no está presente en la versión 92.319 +anterior del kernel, para que el controlador siga funcionando 92.320 +correctamente en esa versión anterior. 92.321 + 92.322 +Una meta útil al escribir un buen parche de backport es hacer parecer 92.323 +que el código hubiera sido escrito para la versión vieja del kernel 92.324 +que usted tiene como objetivo. Entre menos intrusivo el parche, más 92.325 +fácil será entenderlo y mantenerlo. Si usted está escribiendo una 92.326 +colección de parches de backport para evitar el efecto de ``nido de 92.327 +ratas'' de tener muchos \texttt{\#ifdef}s (secciones de código fuente 92.328 +que sólo son usados condicionalmente) en su código, no introduzca 92.329 +\texttt{\#ifdef}s dependientes de versiones específicas en los 92.330 +parches. En vez de eso, escriba varios parches, cada uno de ellos 92.331 +haciendo cambios incondicionales, y controle su aplicación usando 92.332 +guardias. 92.333 + 92.334 +Hay dos razones para ubicar los parches de backport en un grupo 92.335 +diferente, aparte de los parches ``regulares'' cuyos efectos son 92.336 +modificados por ellos. La primera es que mezclar los dos hace más 92.337 +difícil usar herramientas como la extensión \hgext{patchbomb} para 92.338 +automatizar el proceso de enviar los parches a un mantenedor oficial. 92.339 +La segunda es que un parche de backport puede perturbar el contexto en 92.340 +el que se aplica un parche regular subsecuente, haciendo imposible 92.341 +aplicar el parche normal limpiamente \emph{sin} que el parche de 92.342 +backport sea aplicado antes. 92.343 + 92.344 +\section{Consejos útiles para hacer desarrollo con MQ} 92.345 + 92.346 +\subsection{Organizar parches en directorios} 92.347 + 92.348 +Si está trabajando en un proyecto grande con MQ, no es difícil 92.349 +acumular un gran número de parches. Por ejemplo, tengo un repositorio 92.350 +de parches que contiene más de 250 parches. 92.351 + 92.352 +Si usted puede agrupar estos parches en categorías lógicas separadas, 92.353 +usted puede almacenarlos en diferentes directorios si lo desea; MQ no 92.354 +tiene problemas manejando nombres de parches que contienen separadores 92.355 +de ruta. 92.356 + 92.357 +\subsection{Ver el historial de un parche} 92.358 +\label{mq-collab:tips:interdiff} 92.359 + 92.360 +Si usted está desarrollando un conjunto de parches en un período de 92.361 +tiempo grande, es una buena idea mantenerlos en un repositorio, como 92.362 +se discutió en la sección~\ref{sec:mq:repo}. Si lo hace, notará 92.363 +rápidamente que usar el comando \hgcmd{diff} para mirar el historial 92.364 +del repositorio no es viable. Esto es debido en parte a que usted está 92.365 +mirando la segunda derivada del código real (el diff de un diff), pero 92.366 +también porque MQ añade ruido al proceso al modificar las marcas de 92.367 +tiempo y los nombres de directorio cuando actualiza un parche. 92.368 + 92.369 +Sin embargo, usted puede usar la extensión \hgext{extdiff}, que es 92.370 +provisto junto con Mercurial, para convertir un diff de dos versiones 92.371 +de un parche en algo legible. Para hacer esto, usted necesitará un 92.372 +paquete de un tercero llamado 92.373 +\package{patchutils}~\cite{web:patchutils}. Éste paquete provee un 92.374 +comando llamado \command{interdiff}, que muestra las diferencias entre 92.375 +dos diffs como un diff. Al usarlo en dos versiones del mismo diff, 92.376 +genera un diff que representa el diff de la primera a la segunda 92.377 +versión. 92.378 + 92.379 +Usted puede habilitar la extensión \hgext{extdiff} de la manera usual, 92.380 +añadiendo una línea a la sección \rcsection{extensions} de su \hgrc. 92.381 +\begin{codesample2} 92.382 + [extensions] 92.383 + extdiff = 92.384 +\end{codesample2} 92.385 +El comando \command{interdiff} espera recibir los nombres de dos 92.386 +ficheros, pero la extensión \hgext{extdiff} le pasa un par de 92.387 +directorios al programa que ejecuta, cada uno de los cuales puede 92.388 +contener una cantidad arbitraria de ficheros. Por esto necesitamos un 92.389 +programa pequeño que ejecute \command{interdiff} en cada par de 92.390 +ficheros de estos dos directorios. Este programa está disponible como 92.391 +\sfilename{hg-interdiff} en el directorio \dirname{examples} del 92.392 +repositorio de código fuente que acompaña a este libro. 92.393 +\excode{hg-interdiff} 92.394 + 92.395 +Con el programa \sfilename{hg-interdiff} en la ruta de búsqueda de su 92.396 +intérprete de comandos, puede ejecutarlo como sigue, desde dentro de 92.397 +un directorio de parches MQ: 92.398 +\begin{codesample2} 92.399 + hg extdiff -p hg-interdiff -r A:B my-change.patch 92.400 +\end{codesample2} 92.401 +Ya que usted seguramente querrá usar este comando tan largo a menudo, 92.402 +puede hacer que \hgext{hgext} lo haga disponible como un comando 92.403 +normal de Mercurial, editando de nuevo su \hgrc. 92.404 +\begin{codesample2} 92.405 + [extdiff] 92.406 + cmd.interdiff = hg-interdiff 92.407 +\end{codesample2} 92.408 +Esto le indica a \hgext{hgext} que ponga a disposición un comando 92.409 +\texttt{interdiff}, con lo que usted puede abreviar la invocación 92.410 +anterior de \hgxcmd{extdiff}{extdiff} a algo un poco más manejable. 92.411 +\begin{codesample2} 92.412 + hg interdiff -r A:B my-change.patch 92.413 +\end{codesample2} 92.414 + 92.415 +\begin{note} 92.416 + %TODO revisar redacción 92.417 + El comando \command{interdiff} trabaja bien sólo si los ficheros 92.418 + contra los cuales son generadas las versiones de un parche se 92.419 + mantienen iguales. Si usted crea un parche, modifica los ficheros 92.420 + subyacentes, y luego regenera el parche, \command{interdiff} podría 92.421 + no producir ningún resultado útil. 92.422 +\end{note} 92.423 + 92.424 +La extensión \hgext{extdiff} es útil para más que solamente mejorar la 92.425 +presentación de los parches~MQ. Para leer más acerca de esto, vaya a 92.426 +la sección~\ref{sec:hgext:extdiff}. 92.427 + 92.428 +%%% Local Variables: 92.429 +%%% mode: latex 92.430 +%%% TeX-master: "00book" 92.431 +%%% End:
93.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 93.2 +++ b/es/mq-ref.tex Thu Jan 29 22:00:07 2009 -0800 93.3 @@ -0,0 +1,378 @@ 93.4 +\chapter{Referencia de las Colas de Mercurial} 93.5 +\label{chap:mqref} 93.6 + 93.7 +\section{Referencia de órdenes MQ} 93.8 +\label{sec:mqref:cmdref} 93.9 + 93.10 +Si desea dar un vistazo a las órdenes que ofrece MQ, use la orden 93.11 +\hgcmdargs{help}{mq}. 93.12 + 93.13 +\subsection{\hgxcmd{mq}{qapplied}---imprimir los parches aplicados} 93.14 + 93.15 +La orden \hgxcmd{mq}{qapplied} imprime la pila actual de parches 93.16 +aplicados. Los parches se imprimen en orden de antigüedad, primero 93.17 +los más antiguos y después los más recientes, por lo tanto el último 93.18 +parche de la lista es el que está en el ``tope''. 93.19 + 93.20 +\subsection{\hgxcmd{mq}{qcommit}---consignar cambios en la cola del repositorio} 93.21 + 93.22 +La orden \hgxcmd{mq}{qcommit} consigna cualquier cambio sobresaliente 93.23 +en el repositorio \sdirname{.hg/patches}. Esta orden solamente 93.24 +funciona si el directorio \sdirname{.hg/patches} es un repositorio, 93.25 +p.e.~usted creó el directorio con 93.26 +\hgcmdargs{qinit}{\hgxopt{mq}{qinit}{-c}} o ejecutó 93.27 +\hgcmd{init} en el directorio después de correr \hgxcmd{mq}{qinit}. 93.28 + 93.29 +Esta orden es un atajo para \hgcmdargs{commit}{--cwd .hg/patches}. 93.30 + 93.31 +\subsection{\hgxcmd{mq}{qdelete}---eliminar un parche del fichero 93.32 + \sfilename{series}} 93.33 + 93.34 +La orden \hgxcmd{mq}{qdelete} elimina la entrada del fichero 93.35 +\sfilename{series} para el parche en el directorio 93.36 +\sdirname{.hg/patches}. No sca el parche si ha sido aplicado. De 93.37 +forma predeterminada no borra el fichero del parche; use la opción 93.38 +\hgxopt{mq}{qdel}{-f} para hacerlo. 93.39 + 93.40 +Opciones: 93.41 +\begin{itemize} 93.42 +\item[\hgxopt{mq}{qdel}{-f}] Elimina el fichero del parche. 93.43 +\end{itemize} 93.44 + 93.45 +\subsection{\hgxcmd{mq}{qdiff}---imprimir la diferencia del último 93.46 + parche aplicado} 93.47 + 93.48 +La orden \hgxcmd{mq}{qdiff} imprime un diff del parche más 93.49 +recientemente aplicado. Es equivalente a \hgcmdargs{diff}{-r-2:-1}. 93.50 + 93.51 +\subsection{\hgxcmd{mq}{qfold}---fusionar (``integrar'') varios parches en 93.52 + uno solo} 93.53 + 93.54 +La orden \hgxcmd{mq}{qfold} fusiona muchos parches en el último parche 93.55 +aplicado, de tal forma que el último parche aplicado es la unión de 93.56 +todos los cambios de los parches en cuestión. 93.57 + 93.58 +Los parches a fusionar no deben haber sido aplicados; 93.59 +\hgxcmd{mq}{qfold} saldrá indicando un error si alguno ha sido 93.60 +aplicado. El orden en el cual los parches se pliegan es 93.61 +significativo; \hgcmdargs{qfold}{a b} significa ``aplique el parche 93.62 +más reciente, seguido de \texttt{a}, y seguido de \texttt{b}''. 93.63 + 93.64 +Los comentarios de los parches integrados se colocan al final de los 93.65 +comentarios del parche destino, con cada bloque de comentarios 93.66 +separado con tres asteriscos (``\texttt{*}''). Se usa la opción 93.67 +\hgxopt{mq}{qfold}{-e} para editar el mensaje de consignación para el 93.68 +conjunto de cambios/parches después de completarse el pliegue. 93.69 + 93.70 +Opciones: 93.71 +\begin{itemize} 93.72 +\item[\hgxopt{mq}{qfold}{-e}] Edita el mensaje de consignación y la 93.73 + descripción del parche del parche que se ha integrado. 93.74 +\item[\hgxopt{mq}{qfold}{-l}] Usa los contenidos del fichero dado como 93.75 + el nuevo mensaje de consignación y descripción del parche para el 93.76 + parche a integrar. 93.77 +\item[\hgxopt{mq}{qfold}{-m}] Usa el texto dado como el mensaje de 93.78 + consignación y descripción del parche para el parche integrado. 93.79 +\end{itemize} 93.80 + 93.81 +\subsection{\hgxcmd{mq}{qheader}---desplegar el encabezado/descripción 93.82 + de un parche} 93.83 + 93.84 +La orden \hgxcmd{mq}{qheader} imprime el encabezado o descripción de 93.85 +un parche. De forma predeterminada, imprime el encabezado del último 93.86 +parche aplicado. Si se da un argumento, imprime el encabezado del 93.87 +parche referenciado. 93.88 + 93.89 +\subsection{\hgxcmd{mq}{qimport}---importar el parche de un tercero en 93.90 + la cola} 93.91 + 93.92 +La orden \hgxcmd{mq}{qimport} añade una entrada de un parche externo 93.93 +al fichero \sfilename{series} y copia el parche en el directorio 93.94 +\sdirname{.hg/patches}. Añade la entrada inmediatamente después del 93.95 +último parche aplicado, pero no introduce el parche. 93.96 + 93.97 +Si el directorio \sdirname{.hg/patches} es un repositorio, 93.98 +\hgxcmd{mq}{qimport} automáticamente hace un \hgcmd{add} del parche 93.99 +importado. 93.100 + 93.101 +\subsection{\hgxcmd{mq}{qinit}---preparar un repositorio para trabajar 93.102 + con MQ} 93.103 + 93.104 +La orden \hgxcmd{mq}{qinit} prepara un repositorio para trabajar con 93.105 +MQ. Crea un directorio llamado \sdirname{.hg/patches}. 93.106 + 93.107 +Opciones: 93.108 +\begin{itemize} 93.109 +\item[\hgxopt{mq}{qinit}{-c}] Crea \sdirname{.hg/patches} como un 93.110 + repositorio por sí mismo. También crea un fichero 93.111 + \sfilename{.hgignore} que ignorará el fichero \sfilename{status}. 93.112 +\end{itemize} 93.113 + 93.114 +Cuando el directorio \sdirname{.hg/patches} es un repositorio, las órdenes 93.115 +\hgxcmd{mq}{qimport} y \hgxcmd{mq}{qnew} hacen \hgcmd{add} 93.116 +automáticamente a los parches nuevos. 93.117 + 93.118 +\subsection{\hgxcmd{mq}{qnew}---crear un parche nuevo} 93.119 + 93.120 +La orden \hgxcmd{mq}{qnew} crea un parche nuevo. Exige un argumento, 93.121 +el nombre que se usará para tal parche. El parche recién creado está 93.122 +vacío inicialmente. Se añade al fichero \sfilename{series} después 93.123 +del último parche aplicado, y se introduce en el tope de ese parche. 93.124 + 93.125 +Si \hgxcmd{mq}{qnew} encuentra ficheros modificados en el directorio 93.126 +de trabajo, rehusará crear un parche nuevo a meos que se emplee 93.127 +\hgxopt{mq}{qnew}{-f} la opción (ver más adelante). Este 93.128 +comportamiento le permite hacer \hgxcmd{mq}{qrefresh} al último parche 93.129 +aplicado antes de aplicar un parche nuevo encima de este. 93.130 + 93.131 +Opciones: 93.132 +\begin{itemize} 93.133 +\item[\hgxopt{mq}{qnew}{-f}] Crea un parche nuevo si los contenidos 93.134 + del directorio actual han sido modificados. Cualquier modificación 93.135 + significativa se añade al parche recientemente creado, de tal forma 93.136 + que al finalizar la orden, el directorio de trabajo no lucirá 93.137 + modificado. 93.138 +\item[\hgxopt{mq}{qnew}{-m}] Usa el texto dado como el mensaje de 93.139 + consignación. Este texto se almacenará al principio del fichero del 93.140 + parche, antes de los datos del parche. 93.141 +\end{itemize} 93.142 + 93.143 +\subsection{\hgxcmd{mq}{qnext}---imprimir el nombre del próximo parche} 93.144 + 93.145 +La orden \hgxcmd{mq}{qnext} imprime el nombre del siguiente parche en 93.146 +el fichero \sfilename{series} a continuación del último parche 93.147 +aplicado. Este parche sería el próximo parche a aplicar si se 93.148 +ejecutara la orden \hgxcmd{mq}{qpush}. 93.149 + 93.150 +\subsection{\hgxcmd{mq}{qpop}---sustraer parches de la pila} 93.151 + 93.152 +La orden \hgxcmd{mq}{qpop} elimina los parches aplicados del tope de 93.153 +la pila de parches aplicados. De forma predeterminada solamente 93.154 +remueve un parche. 93.155 + 93.156 +Esta orden elimina los conjuntos de cambios que representan los 93.157 +parches sustraídos del repositorio, y actualiza el directorio de 93.158 +trabajo para deshacer los efectos de los parches. 93.159 + 93.160 +Esta orden toma un argumento opcional, que usa como el nombre o el 93.161 +índice del parche que desea sustraer. Si se da el nombre, sustraerá 93.162 +los parches hasta que el parche nombrado sea el último parche 93.163 +aplicado. Si se da un número, \hgxcmd{mq}{qpop} lo trata como un 93.164 +índice dentro del fichero \sfilename{series}, contando desde 93.165 +cero (no cuenta las líneas vacías o aquellas que sean únicamente 93.166 +comentarios). Sustrae los parches hasta que el parche identificado 93.167 +por el índice sea el último parche aplicado. 93.168 + 93.169 +La orden \hgxcmd{mq}{qpop} no lee o escribe parches en el fichero 93.170 +\sfilename{series}. \hgxcmd{mq}{qpop} se constituye por tanto en una 93.171 +forma segura de sustraer un parche del fichero \sfilename{series} o un 93.172 +parche que ha eliminado o renombrado completamente. En los dos 93.173 +últimos casos, use el nombre del parche tal como lo hizo cuando lo 93.174 +aplicó. 93.175 + 93.176 +De forma predeterminada, la orden \hgxcmd{mq}{qpop} no sustraerá 93.177 +parche alguno si el directorio de trabajo ha sido modificado. Puede 93.178 +modificar este comportamiento con la opción \hgxopt{mq}{qpop}{-f}, que 93.179 +revierte todas las modificaciones del directorio de trabajo. 93.180 + 93.181 +Opciones: 93.182 +\begin{itemize} 93.183 +\item[\hgxopt{mq}{qpop}{-a}] Sustrae todos los parches aplicados. 93.184 + Restaura el repositorio al estado antes de haber aplicado parche alguno. 93.185 +\item[\hgxopt{mq}{qpop}{-f}] Revertir forzadamente cualquier 93.186 + modificación del directorio de trabajo cuando se hace sustracciones. 93.187 +\item[\hgxopt{mq}{qpop}{-n}] Sustraer un parche de la cola dado un nombre. 93.188 +\end{itemize} 93.189 + 93.190 +La orden \hgxcmd{mq}{qpop} elimina una línea del final del fichero 93.191 +\sfilename{status} por cada parche que se sustrae. 93.192 + 93.193 +\subsection{\hgxcmd{mq}{qprev}---imprimir el nombre del parche anterior} 93.194 + 93.195 +La orden \hgxcmd{mq}{qprev} imprime el nombre del parche en el fichero 93.196 +\sfilename{series} que está antes del último parche aplicado. Este 93.197 +se volverá el último parche aplicado si ejecuta \hgxcmd{mq}{qpop}. 93.198 + 93.199 +\subsection{\hgxcmd{mq}{qpush}---introducir parches a la pila} 93.200 +\label{sec:mqref:cmd:qpush} 93.201 + 93.202 +La orden \hgxcmd{mq}{qpush} añade parches a la pila. De forma 93.203 +predeterminada añade solamente un parche. 93.204 + 93.205 +Esta orden crea un conjunto de cambios que representa cada parche 93.206 +aplicado y actualiza el directorio de trabajo aplicando los efectos de 93.207 +los parches. 93.208 + 93.209 +Los datos predeterminados cuando se crea un conjunto de cambios 93.210 +corresponde a: 93.211 +\begin{itemize} 93.212 +\item La fecha de consignación y zona horaria corresponden a la hora 93.213 + actual de la zona. Dado que tales datos se usan para computar la 93.214 + identidad de un conjunto de cambios, significa que si hace 93.215 + \hgxcmd{mq}{qpop} a un parche y \hgxcmd{mq}{qpush} de nuevo, el 93.216 + conjunto de cambios que introduzca tendrá una identidad distinta a 93.217 + la del conjunto de cambios que sustrajo. 93.218 +\item El autor es el mismo que el predeterminado usado por la orden 93.219 + \hgcmd{commit}. 93.220 +\item El mensaje de consignación es cualquier texto del fichero del 93.221 + parche que viene antes del primer encabezado del diff. Si no hay 93.222 + tal texto, un mensaje predeterminado se sua para identificar el 93.223 + nombre del parche. 93.224 +\end{itemize} 93.225 +Su un parche contiene un encabezado de parche de Mercurial (XXX add 93.226 +link), la información en el encabezado del parche tiene precedencia 93.227 +sobre el predeterminado. 93.228 + 93.229 +Opciones: 93.230 +\begin{itemize} 93.231 +\item[\hgxopt{mq}{qpush}{-a}] Introduce todos los parches que no han 93.232 + sido aplicados del fichero \sfilename{series} hasta que no haya nada 93.233 + más para introducir. 93.234 +\item[\hgxopt{mq}{qpush}{-l}] Añade el nombre del parche al final del 93.235 + mensaje de consignación 93.236 +\item[\hgxopt{mq}{qpush}{-m}] Si un parche no se aplica limpiamente, 93.237 + usa la entrada para un parche en otra cola almacenada para computar 93.238 + los parámetros en una fusión de tres, y aplica una fusión de tres 93.239 + fuentes usando la maquinaria usual de Mercurial. Usa la resolución 93.240 + de la fusión como el contenido del parche nuevo. 93.241 +\item[\hgxopt{mq}{qpush}{-n}] Usa la cola mencionada si se está 93.242 + fusionando en la introducción. 93.243 +\end{itemize} 93.244 + 93.245 +La orden \hgxcmd{mq}{qpush} lee, pero no modifica el fichero 93.246 +\sfilename{series}. Añade al final del fichero \hgcmd{status} una 93.247 +línea por cada parche que se introduce. 93.248 + 93.249 +\subsection{\hgxcmd{mq}{qrefresh}---actualiza el último parche aplicado} 93.250 + 93.251 +La orden \hgxcmd{mq}{qrefresh} actualiza el último parche aplicado. 93.252 +Modifica el parche, elimina el último conjunto de cambios que 93.253 +representó el parche, y crea un nuevo conjunto de cambios para 93.254 +representar el parche modificado. 93.255 + 93.256 +La orden \hgxcmd{mq}{qrefresh} busca las siguientes modificaciones: 93.257 +\begin{itemize} 93.258 +\item Los cambios al mensaje de consignación, p.e.~el texto antes del 93.259 + primer encabezado de diff en el fichero del parche, se replejan en 93.260 + el nuevo conjunto de cambios que representa el parche. 93.261 +\item Las modificaciones a los ficheros a los que se les da 93.262 + seguimiento en el directorio de trabajo se añade al parche. 93.263 +\item Los cambios a los ficheros a los que se les da seguimiento con 93.264 + \hgcmd{add}, \hgcmd{copy}, \hgcmd{remove}, o \hgcmd{rename}. Se 93.265 + añaden al parche los ficheros añadidos, copiados y renombrados, 93.266 + mientras que los ficheros eliminados y las fuentes renombradas se 93.267 + eliminan. 93.268 +\end{itemize} 93.269 + 93.270 +Incluso si \hgxcmd{mq}{qrefresh} no detecta cambios, de todas maneras 93.271 +recrea el conjunto de cambios que representa el cambio. Esto causa 93.272 +que la identidad del conjunto de cambios difiera del conjunto de 93.273 +cambios previo que identificó al parche. 93.274 + 93.275 +Opciones: 93.276 +\begin{itemize} 93.277 +\item[\hgxopt{mq}{qrefresh}{-e}] Modificar la descripción de la 93.278 + consignación y el parche con el editor de texto preferido. 93.279 +\item[\hgxopt{mq}{qrefresh}{-m}] Modificar el mensaje de consignación 93.280 + y la descripción del parche con el texto dado. 93.281 +\item[\hgxopt{mq}{qrefresh}{-l}] Modificar el mensaje de consignación 93.282 + y la descripción del parche con el texto del fichero dado. 93.283 +\end{itemize} 93.284 + 93.285 +\subsection{\hgxcmd{mq}{qrename}---renombrar un parche} 93.286 + 93.287 +La orden \hgxcmd{mq}{qrename} renombra un parche y cambia la entrada 93.288 +del parche en el fichero \sfilename{series}. 93.289 + 93.290 +Con un argumento sencillo, \hgxcmd{mq}{qrename} renombra el último 93.291 +parche aplicado. Con dos argumentos, renombra el primer argumento con 93.292 +el segundo. 93.293 + 93.294 +\subsection{\hgxcmd{mq}{qrestore}---restaurar el estado almacenado de 93.295 + la cola} 93.296 + 93.297 +XXX No idea what this does. 93.298 + 93.299 +\subsection{\hgxcmd{mq}{qsave}---almacena el estado actual de la cola} 93.300 + 93.301 +XXX Likewise. 93.302 + 93.303 +\subsection{\hgxcmd{mq}{qseries}---imprime la serie completa de parches} 93.304 + 93.305 +La orden \hgxcmd{mq}{qseries} imprime la serie completa de parches del 93.306 +fichero \sfilename{series}. Imprime solamente los nombres de los 93.307 +parches sin las líneas en blanco o comentarios. Imprime primero el 93.308 +primero y de último, el último aplicado. 93.309 + 93.310 +\subsection{\hgxcmd{mq}{qtop}---imprime el nombre del parche actual} 93.311 + 93.312 +\hgxcmd{mq}{qtop} imprime el nombre del último parche aplicado. 93.313 + 93.314 +\subsection{\hgxcmd{mq}{qunapplied}---imprimir los parches que aún no 93.315 + se han aplicado} 93.316 + 93.317 +La orden \hgxcmd{mq}{qunapplied} imprime los nombres de los parches 93.318 +del fichero \sfilename{series} que todavía no han sido aplicados. Los 93.319 +imprime de acuerdo al orden en el cual serían introducidos. 93.320 + 93.321 +\subsection{\hgcmd{strip}---remover una revisión y sus descendientes} 93.322 + 93.323 +La orden \hgcmd{strip} remueve una revisión, y todos sus descendientes 93.324 +del repositorio. Deshace los efectos de las revisiones removidas del 93.325 +repositorio, y actualiza el directorio de trabajo hasta el primer 93.326 +padre de la revisión removida. 93.327 + 93.328 +La orden \hgcmd{strip} almacena una copia de segurida de los conjuntos 93.329 +de cambios en un agrupamiento, de forma tal que puedan ser reaplicados 93.330 +en caso de que se hayan removido por equivocación. 93.331 + 93.332 +Opciones: 93.333 +\begin{itemize} 93.334 +\item[\hgopt{strip}{-b}] Almacenar conjuntos de cambios no 93.335 + relacionados que se han mezclado con los conjuntos de cambios que 93.336 + están en franjas con el agrupamiento de copia de seguridad. 93.337 +\item[\hgopt{strip}{-f}] Si una rama tiene varias ramas principales 93.338 + remueve todos los frentes. XXX This should be renamed, y usa 93.339 + \texttt{-f} para desagrupar revisiones cuando hay cambios pendientes. 93.340 +\item[\hgopt{strip}{-n}] No almacene la copia de seguridad agrupada. 93.341 +\end{itemize} 93.342 + 93.343 +\section{Referencia de ficheros de MQ} 93.344 + 93.345 +\subsection{El fichero \sfilename{series}} 93.346 + 93.347 +El fichero \sfilename{series} contiene una lista de los nombres de 93.348 +todos los parches que MQ puede aplicar. Se representa como una lista 93.349 +de nombres, uno por línea. Se ignora el espacio en blanco al 93.350 +principio y al final. 93.351 + 93.352 +Las líneas pueden contener comentario. Un comentario comienza con el 93.353 +caracter ``\texttt{\#}'', y va hasta el final de la línea. Se ignoran 93.354 +las líneas vacías y las que solamente contengan comentarios. 93.355 + 93.356 +En algún momento podría editar el fichero \sfilename{series} a mano, 93.357 +por tal motivo se admiten comentarios y líneas en blanco como se 93.358 +menciono anteriormente. Por ejemplo, puede poner en comentario un 93.359 +parche temporalmente y \hgxcmd{mq}{qpush} omitirá tal parche cuando 93.360 +los aplique. También puede cambiar el orden en el cual se aplican los 93.361 +parches, reordenando las entradas en el fichero \sfilename{series}. 93.362 + 93.363 +También es posible colocar el fichero \sfilename{series} bajo control 93.364 +de revisiones; también es favorable colocar todos los parches que refiera 93.365 +bajo control de revisiones. Si crea un directorio de parches con la 93.366 +opción \hgxopt{mq}{qinit}{-c} de \hgxcmd{mq}{qinit}, esto se hará 93.367 +automáticamente. 93.368 + 93.369 +\subsection{El fichero \sfilename{status}} 93.370 + 93.371 +El fichero \sfilename{status} contiene los nombres y los hashes de los 93.372 +conjuntos de cambios de todos los parches que MQ ha aplicado. A 93.373 +diferencia del fichero \sfilename{series}, este NO ha sido diseñado 93.374 +para ser editado. No debería colocar este fichero bajo el control de 93.375 +revisiones o modificarlo de forma alguna. MQ lo usa estrictamente 93.376 +para administración interna. 93.377 + 93.378 +%%% Local Variables: 93.379 +%%% mode: latex 93.380 +%%% TeX-master: "00book" 93.381 +%%% End:
94.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 94.2 +++ b/es/mq-stack.svg Thu Jan 29 22:00:07 2009 -0800 94.3 @@ -0,0 +1,280 @@ 94.4 +<?xml version="1.0" encoding="UTF-8" standalone="no"?> 94.5 +<!-- Created with Inkscape (http://www.inkscape.org/) --> 94.6 +<svg 94.7 + xmlns:dc="http://purl.org/dc/elements/1.1/" 94.8 + xmlns:cc="http://creativecommons.org/ns#" 94.9 + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 94.10 + xmlns:svg="http://www.w3.org/2000/svg" 94.11 + xmlns="http://www.w3.org/2000/svg" 94.12 + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" 94.13 + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" 94.14 + width="744.09448819" 94.15 + height="1052.3622047" 94.16 + id="svg2" 94.17 + sodipodi:version="0.32" 94.18 + inkscape:version="0.46" 94.19 + sodipodi:docname="mq-stack.svg" 94.20 + sodipodi:docbase="/home/bos/hg/hgbook/en" 94.21 + inkscape:output_extension="org.inkscape.output.svg.inkscape"> 94.22 + <defs 94.23 + id="defs4"> 94.24 + <inkscape:perspective 94.25 + sodipodi:type="inkscape:persp3d" 94.26 + inkscape:vp_x="0 : 526.18109 : 1" 94.27 + inkscape:vp_y="0 : 1000 : 0" 94.28 + inkscape:vp_z="744.09448 : 526.18109 : 1" 94.29 + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" 94.30 + id="perspective2525" /> 94.31 + </defs> 94.32 + <sodipodi:namedview 94.33 + id="base" 94.34 + pagecolor="#ffffff" 94.35 + bordercolor="#666666" 94.36 + borderopacity="1.0" 94.37 + inkscape:pageopacity="0.0" 94.38 + inkscape:pageshadow="2" 94.39 + inkscape:zoom="1.4142136" 94.40 + inkscape:cx="299.33323" 94.41 + inkscape:cy="815.646" 94.42 + inkscape:document-units="px" 94.43 + inkscape:current-layer="layer1" 94.44 + inkscape:window-width="1014" 94.45 + inkscape:window-height="689" 94.46 + inkscape:window-x="89" 94.47 + inkscape:window-y="25" 94.48 + showgrid="false" /> 94.49 + <metadata 94.50 + id="metadata7"> 94.51 + <rdf:RDF> 94.52 + <cc:Work 94.53 + rdf:about=""> 94.54 + <dc:format>image/svg+xml</dc:format> 94.55 + <dc:type 94.56 + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> 94.57 + </cc:Work> 94.58 + </rdf:RDF> 94.59 + </metadata> 94.60 + <g 94.61 + inkscape:label="Layer 1" 94.62 + inkscape:groupmode="layer" 94.63 + id="layer1"> 94.64 + <rect 94.65 + style="fill:#0000ff;fill-opacity:0.75;fill-rule:evenodd;stroke:#3c3c3c;stroke-width:1.05063355px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" 94.66 + id="rect1307" 94.67 + width="202.93683" 94.68 + height="24.243662" 94.69 + x="230.01944" 94.70 + y="221.70146" /> 94.71 + <text 94.72 + xml:space="preserve" 94.73 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" 94.74 + x="237.89606" 94.75 + y="237.13383" 94.76 + id="text1309"><tspan 94.77 + sodipodi:role="line" 94.78 + id="tspan1311" 94.79 + x="237.89606" 94.80 + y="237.13383">prevent-compiler-reorder.patch</tspan></text> 94.81 + <rect 94.82 + style="fill:#7979ff;fill-opacity:0.875;fill-rule:evenodd;stroke:#3c3c3c;stroke-width:1.05063355px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" 94.83 + id="rect1320" 94.84 + width="202.93683" 94.85 + height="24.243662" 94.86 + x="230.01936" 94.87 + y="251.34325" /> 94.88 + <text 94.89 + xml:space="preserve" 94.90 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" 94.91 + x="237.89598" 94.92 + y="266.77563" 94.93 + id="text1322"><tspan 94.94 + sodipodi:role="line" 94.95 + id="tspan1324" 94.96 + x="237.89598" 94.97 + y="266.77563">namespace-cleanup.patch</tspan></text> 94.98 + <rect 94.99 + style="fill:#7979ff;fill-opacity:0.875;fill-rule:evenodd;stroke:#3c3c3c;stroke-width:1.05063355px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" 94.100 + id="rect2217" 94.101 + width="202.93683" 94.102 + height="24.243662" 94.103 + x="230.01936" 94.104 + y="280.98505" /> 94.105 + <text 94.106 + xml:space="preserve" 94.107 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" 94.108 + x="237.89598" 94.109 + y="296.41742" 94.110 + id="text2219"><tspan 94.111 + sodipodi:role="line" 94.112 + id="tspan2221" 94.113 + x="237.89598" 94.114 + y="296.41742">powerpc-port-fixes.patch</tspan></text> 94.115 + <rect 94.116 + style="fill:#7979ff;fill-opacity:0.875;fill-rule:evenodd;stroke:#3c3c3c;stroke-width:1.05063355px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" 94.117 + id="rect3114" 94.118 + width="202.93683" 94.119 + height="24.243662" 94.120 + x="230.01936" 94.121 + y="310.6268" /> 94.122 + <text 94.123 + xml:space="preserve" 94.124 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" 94.125 + x="237.89598" 94.126 + y="326.05917" 94.127 + id="text3116"><tspan 94.128 + sodipodi:role="line" 94.129 + id="tspan3118" 94.130 + x="237.89598" 94.131 + y="326.05917">report-devinfo-correctly.patch</tspan></text> 94.132 + <text 94.133 + xml:space="preserve" 94.134 + style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" 94.135 + x="200.01021" 94.136 + y="191.68094" 94.137 + id="text3170" 94.138 + sodipodi:linespacing="125%"><tspan 94.139 + sodipodi:role="line" 94.140 + id="tspan3172" 94.141 + x="200.01021" 94.142 + y="191.68094" 94.143 + style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Bitstream Vera Sans">{</tspan></text> 94.144 + <text 94.145 + xml:space="preserve" 94.146 + style="font-size:15.25329685px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" 94.147 + x="255.26627" 94.148 + y="248.79449" 94.149 + id="text3190" 94.150 + sodipodi:linespacing="125%" 94.151 + transform="scale(0.786716,1.271107)"><tspan 94.152 + sodipodi:role="line" 94.153 + id="tspan3192" 94.154 + x="255.26627" 94.155 + y="248.79449" 94.156 + style="font-size:61.01318741px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Bitstream Vera Sans">{</tspan></text> 94.157 + <text 94.158 + xml:space="preserve" 94.159 + style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" 94.160 + x="195.86807" 94.161 + y="173.17117" 94.162 + id="text4085" 94.163 + sodipodi:linespacing="125%"><tspan 94.164 + sodipodi:role="line" 94.165 + id="tspan4087" 94.166 + x="195.86807" 94.167 + y="173.17117" 94.168 + style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;writing-mode:lr-tb;text-anchor:end;font-family:Bitstream Vera Sans">presente en la serie,</tspan><tspan 94.169 + sodipodi:role="line" 94.170 + x="195.86807" 94.171 + y="188.17117" 94.172 + id="tspan4089" 94.173 + style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;writing-mode:lr-tb;text-anchor:end;font-family:Bitstream Vera Sans">pero no aplicado</tspan></text> 94.174 + <text 94.175 + xml:space="preserve" 94.176 + style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" 94.177 + x="195.0712" 94.178 + y="288.91745" 94.179 + id="text4091" 94.180 + sodipodi:linespacing="125%"><tspan 94.181 + sodipodi:role="line" 94.182 + id="tspan4093" 94.183 + x="195.0712" 94.184 + y="288.91745" 94.185 + style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;writing-mode:lr-tb;text-anchor:end;font-family:Bitstream Vera Sans">parches aplicados,</tspan><tspan 94.186 + sodipodi:role="line" 94.187 + x="195.0712" 94.188 + y="303.91745" 94.189 + id="tspan4111" 94.190 + style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;writing-mode:lr-tb;text-anchor:end;font-family:Bitstream Vera Sans">Conjuntos de cambios presentes</tspan></text> 94.191 + <text 94.192 + xml:space="preserve" 94.193 + style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" 94.194 + x="195.0712" 94.195 + y="229.28813" 94.196 + id="text4095" 94.197 + sodipodi:linespacing="125%"><tspan 94.198 + sodipodi:role="line" 94.199 + id="tspan4097" 94.200 + x="195.0712" 94.201 + y="229.28813" 94.202 + style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;writing-mode:lr-tb;text-anchor:end;font-family:Bitstream Vera Sans">parche aplicado</tspan><tspan 94.203 + sodipodi:role="line" 94.204 + x="195.0712" 94.205 + y="244.28813" 94.206 + id="tspan4109" 94.207 + style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;writing-mode:lr-tb;text-anchor:end;font-family:Bitstream Vera Sans">más recientemente</tspan></text> 94.208 + <text 94.209 + xml:space="preserve" 94.210 + style="font-size:12px;font-style:normal;font-weight:normal;opacity:1;fill:#666666;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" 94.211 + x="450.4975" 94.212 + y="238.29692" 94.213 + id="text4137"><tspan 94.214 + sodipodi:role="line" 94.215 + id="tspan4139" 94.216 + x="450.4975" 94.217 + y="238.29692">201ad3209902</tspan></text> 94.218 + <text 94.219 + xml:space="preserve" 94.220 + style="font-size:12px;font-style:normal;font-weight:normal;opacity:1;fill:#989898;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" 94.221 + x="450.05804" 94.222 + y="267.93872" 94.223 + id="text4141"><tspan 94.224 + sodipodi:role="line" 94.225 + id="tspan4143" 94.226 + x="450.05804" 94.227 + y="267.93872">126b84e593ae</tspan></text> 94.228 + <text 94.229 + xml:space="preserve" 94.230 + style="font-size:12px;font-style:normal;font-weight:normal;opacity:1;fill:#989898;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" 94.231 + x="450.6557" 94.232 + y="297.58051" 94.233 + id="text4145"><tspan 94.234 + sodipodi:role="line" 94.235 + id="tspan4147" 94.236 + x="450.6557" 94.237 + y="297.58051">a655daf15409</tspan></text> 94.238 + <text 94.239 + xml:space="preserve" 94.240 + style="font-size:12px;font-style:normal;font-weight:normal;opacity:1;fill:#989898;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" 94.241 + x="450.71429" 94.242 + y="327.22226" 94.243 + id="text4149"><tspan 94.244 + sodipodi:role="line" 94.245 + id="tspan4151" 94.246 + x="450.71429" 94.247 + y="327.22226">e50d59aaea3a</tspan></text> 94.248 + <rect 94.249 + style="fill:#d7d7ff;fill-opacity:0.875;fill-rule:evenodd;stroke:#a6a6a6;stroke-width:1.05063355px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" 94.250 + id="rect3106" 94.251 + width="202.93683" 94.252 + height="24.243662" 94.253 + x="230.01936" 94.254 + y="150.41792" /> 94.255 + <text 94.256 + xml:space="preserve" 94.257 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#808080;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" 94.258 + x="237.89598" 94.259 + y="165.8503" 94.260 + id="text3108"><tspan 94.261 + sodipodi:role="line" 94.262 + id="tspan3110" 94.263 + x="237.89598" 94.264 + y="165.8503">forbid-illegal-params.patch</tspan></text> 94.265 + <rect 94.266 + style="fill:#d7d7ff;fill-opacity:0.875;fill-rule:evenodd;stroke:#a6a6a6;stroke-width:1.05063355px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" 94.267 + id="rect2241" 94.268 + width="202.93683" 94.269 + height="24.243662" 94.270 + x="230.16466" 94.271 + y="180.05968" /> 94.272 + <text 94.273 + xml:space="preserve" 94.274 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#808080;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" 94.275 + x="238.04128" 94.276 + y="195.49205" 94.277 + id="text2243"><tspan 94.278 + sodipodi:role="line" 94.279 + id="tspan2245" 94.280 + x="238.04128" 94.281 + y="195.49205">fix-memory-leak.patch</tspan></text> 94.282 + </g> 94.283 +</svg>
95.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 95.2 +++ b/es/mq.tex Thu Jan 29 22:00:07 2009 -0800 95.3 @@ -0,0 +1,1103 @@ 95.4 +\chapter{Administración de cambios con Colas de Mercurial} 95.5 +\label{chap:mq} 95.6 + 95.7 +\section{El problema de la administración de parches} 95.8 +\label{sec:mq:patch-mgmt} 95.9 + 95.10 +Un escenario frecuente: usted necesita instalar un paquete de software 95.11 +desde las fuentes, pero encuentra un fallo que debe arreglar antes de 95.12 +poder comenzar a usarlo. Hace sus cambios, y se olvida del paquete 95.13 +por un tiempo, unos meses después necesita actualizar a una nueva 95.14 +versión del paquete. Si la nueva versión del paquete todavía tiene el 95.15 +fallo, debe extraer su arreglo del árbol de fuentes anteriores y 95.16 +aplicarlo a la nueva versión. Una tarea tediosa en la cual es fácil 95.17 +equivocarse. 95.18 + 95.19 +Este es un caso simple del problema del ``manejo de parches''. Usted 95.20 +tiene un árbol de fuentes del ``mantenedor principal'' que no puede 95.21 +cambiar: necesita hacer algunos cambios locales sobre el árbol 95.22 +principal; y desearía poder mantener tales cambios separados, de forma 95.23 +tal que pueda aplicarlos a versiones más nuevas del árbol principal. 95.24 + 95.25 +El problema de administración de parches surge en muchas situaciones. 95.26 +Probablemente la más visible es cuando un usuario de un proyecto de 95.27 +software de fuentes abiertas contribuye con un arreglo de un fallo o 95.28 +una nueva característica a los mantenedores del proyecto en la forma 95.29 +de un parche. 95.30 + 95.31 +Aquellos que distribuyen sistemas operativos que incluyen programas 95.32 +abiertos usualmente requieren hacer cambios en los paquetes que 95.33 +distribuyen de tal forma que se armen apropiadamente en sus ambientes. 95.34 + 95.35 +Cuando hay pocos cambios por mantener, es muy sencillo administrar un 95.36 +solo parche con los programas estándar \command{diff} y 95.37 +\command{patch} (ver la sección~\ref{sec:mq:patch} para ver cómo 95.38 +emplear tales herramientas). Cuando la cantidad de cambios comienza a 95.39 +crecer, tiene sentido mantener parches como ``porciones de trabajo'' 95.40 +individual, de forma que cada cambio contiene solamente un arreglo de 95.41 +un fallo (el parche puede modificar varios ficheros, pero está 95.42 +``haciendo una sola cosa''), y puede tener cierta cantidad de tales 95.43 +parches para diferentes fallos y cambios locales. En esta situación, 95.44 +si envía un parche que arregla un fallo a los mantenedores principales 95.45 +de un paquete y ellos incluyen su arreglo en una publicación 95.46 +posterior, puede deshacerse de tal parche cuando se actualice a la 95.47 +nueva versión. 95.48 + 95.49 +Mantener un solo parche frente a un árbol principal es algo tedioso y 95.50 +es fácil equivocarse, pero no es difícil. Aunque, la complejidad del 95.51 +problema crece rápidamente a medida que la cantidad de parches que 95.52 +tiene que mantener crece. Con más que una pequeña cantidad de 95.53 +cambios, entender cuáles ha aplicado se convierte de algo desordenado 95.54 +a algo avasallante. 95.55 + 95.56 +Afortunadamente Mercurial provee una extensión poderos: Colas de 95.57 +Mercurial (o simplemente ``MQ''), que simplifica en gran medida el 95.58 +problema de administración de parches. 95.59 + 95.60 +\section{La prehistoria de las Colas de Mercurial} 95.61 +\label{sec:mq:history} 95.62 + 95.63 +A finales de los 90s, muchos desarrolladores del núcleo de Linux 95.64 +comenzaron a mantener ``series de parches'' que modificaron el 95.65 +comportamiento del núcleo de Linux. Algunos se enfocaban en 95.66 +estabilidad, otros en aumentar las características, y otros un poco 95.67 +más especulativos. 95.68 + 95.69 +Los tamaños de las series de parches crecieron rápidamente. En el 95.70 +2002, Andrew Morton publicó algunos guiones de línea de órdenes que 95.71 +estuvo usando para automatizar la tarea de administrar su cola de 95.72 +parches. Andrew usó exitósamente tales guiones para administrar 95.73 +centenas (a veces millares) de parches en el núcleo de Linux. 95.74 + 95.75 +\subsection{Trabajar parches con quilt} 95.76 +\label{sec:mq:quilt} 95.77 + 95.78 +A comienzos del 2003, Andreas Gruenbacher y Martin Quinson tomaron la 95.79 +aproximación de los guiones de Andrew y publicaron una herramienta 95.80 +llamada 95.81 +``patchwork quilt''~\cite{web:quilt}, o simplemente ``quilt'' 95.82 +(ver~\cite{gruenbacher:2005} el paper que lo describe). Dado que 95.83 +quilt automatizaba sustancialmente la administración de parches, fue 95.84 +adoptado en gran medida por desarrolladores de programas abiertos. 95.85 + 95.86 +Quilt maneja una \emph{pila de parches} sobre un árbol de directorios. 95.87 +Para comenzar, usted le indica a quilt que administre un árbol de 95.88 +directorios, le indica qué ficheros manejar; Este almacena los nombres 95.89 +y los contenidos de estos ficheros. Para arreglar un fallo, usted 95.90 +crea un nuevo parche (con una sola orden), edita los ficheros que está 95.91 +arreglando y ``refresca'' el parche. 95.92 + 95.93 +El paso de refresco hace que quilt revise el árbol de directorios; 95.94 +actualiza el parche con todos los cambios que usted haya hecho. Puede 95.95 +crear otro parche sobre el primero, que hará seguimiento de los 95.96 +cambios requeridos para modificar el árbol desde ``el árbol con un 95.97 +parch aplicado'' a un ``árbol con dos parches aplicados''. 95.98 + 95.99 +Usted puede \emph{elegir} qué cambios desea aplicar al árbol. Si 95.100 +``pop''\ndt{saca} un parche, los cambios hechos por tal parchve 95.101 +desapareceŕan del árbol de directorios. Quilt recuerda qué parches ha 95.102 +sacado, para que pueda ``introducirlos''\ndt{push} posteriormente, así el 95.103 +árbol de directorios se restaurará con las modificaciones que vienen 95.104 +del parche. Lo más importante es que puede ejecutar la orden 95.105 +``refresh'' en cualquier momento, y el último parche será 95.106 +actualizado. Esto significa que puede, en cualquier momento, cambiar 95.107 +qué parches serán aplicados y qué modificaciones hacen ellos. 95.108 + 95.109 +Quilt no tiene nada que ver con herramientas de control de versiones, 95.110 +y puede trabajar bien sobre un conjunto de fuentes que viene de un 95.111 +fichero comprimido y empaquetado o una copia de trabajo de Subversion. 95.112 + 95.113 +\subsection{Pasar de trabajo con parches con Quilt hacia Colas de Mercurial} 95.114 +\label{sec:mq:quilt-mq} 95.115 + 95.116 +A mediados de 2005, Chris Mason tomó las características de quilt y 95.117 +escribió una extensión que llamó Colas de Mercurial\ndt{Mercurial 95.118 +Queues}, que proporcionó un comportamiento a Mercurial al estilo 95.119 +quilt. 95.120 + 95.121 +La diferencia clave entre quilt y MQ es que quilt no sabe nada acerca 95.122 +del sistema de control de revisiones, mientras que MQ está 95.123 +\emph{integrado} con Mercurial. Cada parche que usted introduce se 95.124 +representa como un conjunto de cambios en Mercurial. Si sustrae un 95.125 +parche, el conjunto de cambios desaparece.\ndt{introduce originalmente es 95.126 +push y pop es sustraer en este contexto, usaremos el original en inglés 95.127 +cuando encontremos que facilita la comprensión} 95.128 + 95.129 +Dado que quilt no se preocupa por las herramientas de control de 95.130 +revisiones, continúa siendo una porción de software tremendamente útil 95.131 +para aquellas situaciones en las cuales no puede usar Mercurial y MQ. 95.132 + 95.133 +\section{La gran ventaja de MQ} 95.134 + 95.135 +No puedo sobreestimar el valor que MQ ofrece en la unificación de 95.136 +parches y el control de revisiones. 95.137 + 95.138 +La principal razón por la cual los parches han persistido en el mundo 95.139 +del software libre y de fuentes abiertas--a pesar de la creciente 95.140 +disponibilidad de herramientas poderosas de control de revisiones-- es 95.141 +la \emph{agilidad} que ofrecen. 95.142 + 95.143 +Las herramientas tradicionales de control de revisiones llevan un 95.144 +registro permanente e irreversible de todo lo que usted hace. A pesar 95.145 +de que esto tiene gran valor, también es bastante sutil. Si requiere 95.146 +realizar un experimento ((((wild-eyed)))), debe ser cuidadoso en cómo 95.147 +lo hace, o puede dejar trazas innecesarias--o peor aún, 95.148 +desconcertantes o desestabilizantes--- de los pasos y errores en el 95.149 +registro de revisiones de forma permanente. 95.150 + 95.151 +En contraste, con la cohesión de MQ con el control de revisiones 95.152 +distribuidos y los parches, resulta más sencillo aislar su trabajo. 95.153 +Sus parches viven encima del historial de revisiones normales, y 95.154 +puede hacer que ellos desaparezcan o reaparezcan cuando lo desee. Si 95.155 +no le gusta un parche, puede desecharlo. Si un parche no satisface 95.156 +todo lo que usted desea, puede arreglarlo---tantas veces como lo 95.157 +requiera, hasta que lo haya refinado lo suficiente hacia sus 95.158 +expectativas. 95.159 + 95.160 +Por ejemplo, la integración de parches con el control de revisiones 95.161 +hace que el entender los parches y revisar sus efectos---y sus 95.162 +interacciones con el código en el cuál están enlazados--- sea 95.163 +\emph{mucho} más sencillo. Dado que todo parche que se aplique tiene 95.164 +un conjunto de cambios asociado, puede usar 95.165 +\hgcmdargs{log}{\emph{filename}} para ver qué conjuntos de cambios y 95.166 +parches afectaron un fichero. Puede usar la orden \hgext{bisect} para 95.167 +hacer una búsqueda binaria sobre todos los conjuntos de cambios y 95.168 +parches aplicados para ver dónde se introdujo un fallo o dónde fue 95.169 +arreglado. Puede usar la orden \hgcmd{annotate} para ver qué 95.170 +conjuntos de cambios o parches modificaron una línea particular de un 95.171 +fichero fuente. Y mucho más. 95.172 + 95.173 +\section{Entender los parches} 95.174 +\label{sec:mq:patch} 95.175 + 95.176 +Dado que MQ no esconde su naturaleza parche-céntrica, es muy útil para 95.177 +entender de qué se tratan los parches, y un poco acerca de las 95.178 +herramientas que trabajan con ellos. 95.179 + 95.180 +La orden de Unix tradicional \command{diff} compara dos ficheros, e 95.181 +imprime una lista de diferencias de sus líneas. La orden 95.182 +\command{patch} entiende esas diferencias como \emph{modificaciones} 95.183 +para construir un fichero. Vea en la figura~\ref{ex:mq:diff} un 95.184 +ejemplo sencillo de tales órdenes en acción. 95.185 + 95.186 +\begin{figure}[ht] 95.187 + \interaction{mq.dodiff.diff} 95.188 + \caption{Uso sencillo de las órdenes \command{diff} y \command{patch}} 95.189 + \label{ex:mq:diff} 95.190 +\end{figure} 95.191 + 95.192 +El tipo de fichero que \command{diff} genera (y que \command{patch} 95.193 +toma como entrada) se llama un ``parche'' o un ``diff''; no hay 95.194 +diferencia entre un parche y un diff. (Usaremos el término ``parche'', 95.195 +dado que es el que más comunmente se usa.) 95.196 + 95.197 +Un parche puede comenzar con un texto arbitrario; la orden \command{patch} 95.198 +ignora este texto, pero MQ lo usa como el mensaje de consignación 95.199 +cuando se crean conjuntos de cambios. Para encontrar el inicio del 95.200 +contenido de un parche, la orden \command{patch} busca la primera 95.201 +línea que comience con la cadena ``\texttt{diff~-}''. 95.202 + 95.203 +MQ trabaja con diffs \emph{unificados} (\command{patch} acepta varios 95.204 +formatos de diff adicionales, pero MQ no). Un diff unificado contiene 95.205 +dos clases de encabezados. El \emph{encabezado de fichero} describe 95.206 +el fichero que se está modificando; contiene el nombre del fichero a 95.207 +modificar. Cuando \command{patch} ve un nuevo encabezado de fichero, 95.208 +busca un fichero con ese nombre para modificarlo. 95.209 + 95.210 +Después del encabezaado vienen varios \emph{trozos}. Cada trozo 95.211 +comienza con un encabezado; que identifica el rango de líneas del 95.212 +fichero que el trozo debe modificar. Después del encabezado, un trozo 95.213 +comienza y termina con unas pocas líneas (usualmente tres) de texto del 95.214 +fichero que no han sido modificadas; las cuales llamamos el 95.215 +\emph{contexto} del trozo. Si solamente hay una pequeña cantidad de 95.216 +contexto entre trozos sucesivos, \command{diff} no imprime un nuevo 95.217 +encabezado para el trozo, continua integrando los trozos, con unas 95.218 +líneas de contexto entre las modificaciones. 95.219 + 95.220 +Cada línea de contexto comienza con un caracter de espacio. En el 95.221 +trozo, si una línea comienza con ``\texttt{-}'' significa ``elimine 95.222 +esta línea'', si la línea comienza con un ``\texttt{+}'' significa 95.223 +``inserte esta línea''. Por ejemplo, una línea que se modifica se 95.224 +representa con una línea eliminada y una línea insertada. 95.225 + 95.226 +Retomaremos aspectos más sutiles acerca de parches posteriormente (en 95.227 +la sección~\ref{sec:mq:adv-patch}), pero en el momento usted ya 95.228 +debería tener suficiente información para usar MQ. 95.229 + 95.230 +\section{Comenzar a usar Colas de Mercurial} 95.231 +\label{sec:mq:start} 95.232 + 95.233 +Dado que MQ está implementado como una extensión, debe habilitarla 95.234 +explícitamente antes de comenzar a usarla. (No necesita descargar 95.235 +nada; MQ viene con la distribución estándar de Mercurial.) Para 95.236 +habilitar MQ, edite su fichero \tildefile{.hgrc}, y añada las líneas 95.237 +de la figura~\ref{ex:mq:config}. 95.238 + 95.239 +\begin{figure}[ht] 95.240 + \begin{codesample4} 95.241 + [extensions] 95.242 + hgext.mq = 95.243 + \end{codesample4} 95.244 + \label{ex:mq:config} 95.245 + \caption{Líneas a añadir en \tildefile{.hgrc} para habilitar la extensión MQ} 95.246 +\end{figure} 95.247 + 95.248 +Cuando la extensión esté habilitada, aparecerán varios comandos. Para 95.249 +verificar que la extensión está trabajando, puede usar \hgcmd{help} 95.250 +para ver si la orden \hgxcmd{mq}{qinit} está disponible; vea un 95.251 +ejemplo en la figura~\ref{ex:mq:enabled}. 95.252 + 95.253 +\begin{figure}[ht] 95.254 + \interaction{mq.qinit-help.help} 95.255 + \caption{Cómo verificar que MQ está habilitado} 95.256 + \label{ex:mq:enabled} 95.257 +\end{figure} 95.258 + 95.259 +Puede usar MQ en \emph{cualquier} repositorio de Mercurial, y sus 95.260 +comandos solamente operarán con tal repositorio. Para comenzar, basta 95.261 +con preparar el repositorio con la orden \hgxcmd{mq}{qinit} (ver la 95.262 +figura~\ref{ex:mq:qinit}). Esta orden crea un directorio vacío 95.263 +llamado \sdirname{.hg/patches}, donde MQ mantendrá sus metadatos. Como 95.264 +otras ordenes de Mercurial, la orden \hgxcmd{mq}{qinit} no imprime 95.265 +nada cuando es exitosa. 95.266 + 95.267 +\begin{figure}[ht] 95.268 + \interaction{mq.tutorial.qinit} 95.269 + \caption{Preparar un repositorio para usar MQ} 95.270 + \label{ex:mq:qinit} 95.271 +\end{figure} 95.272 + 95.273 +\begin{figure}[ht] 95.274 + \interaction{mq.tutorial.qnew} 95.275 + \caption{Crear un nuevo parche} 95.276 + \label{ex:mq:qnew} 95.277 +\end{figure} 95.278 + 95.279 +\subsection{Crear un nuevo parche} 95.280 + 95.281 +Para comenzar a trabajar en un nuevo parche use la orden 95.282 +\hgxcmd{mq}{qnew}. Esta orden recibe un argumento, el nombre del 95.283 +parche a crear. MQ lo usará como el nombre del fichero en el 95.284 +directorio \sdirname{.hg/patches}, como puede apreciarlo en la 95.285 +figura~\ref{ex:mq:qnew}. 95.286 + 95.287 +También hay otros dos nuevos ficheros en el directorio 95.288 +\sdirname{.hg/patches}: \sfilename{series} y \sfilename{status}. El 95.289 +fichero \sfilename{series} lista todos los parches de los cuales MQ 95.290 +tiene noticia para este repositorio, con un parche por línea. 95.291 +Mercurial usa el fichero \sfilename{status} para mantener registros 95.292 +interns; da seguimiento a todos los parches que MQ ha \emph{aplicado} 95.293 +en el repositorio. 95.294 + 95.295 +\begin{note} 95.296 + En ciertas ocasiones usted querrá editar el fichero 95.297 + \sfilename{series} a mano; por ejemplo, cambiar el orden en que se 95.298 + aplican ciertos parches. A pesar de esto, es una mala idea editar 95.299 + manualmente el fichero \sfilename{status}, dado que es fácil 95.300 + desorientar a MQ acerca de lo que está pasando. 95.301 +\end{note} 95.302 + 95.303 +Una vez que haya creado un nuevo parche, puede editar los ficheros en 95.304 +el directorio de trabajo, como lo haría usualmente. Toda las órdenes 95.305 +que de a Mercurial, tales como \hgcmd{diff} y \hgcmd{annotate}, 95.306 +trabajarán de la misma forma como lo han hecho antes. 95.307 + 95.308 +\subsection{Refrescar un parche} 95.309 + 95.310 +Cuando usted llega a un punto en el cual desea guardar su trabajo, use 95.311 +la orden \hgxcmd{mq}{qrefresh} (figura~\ref{ex:mq:qnew}) para 95.312 +actualizar el parche en el cual está trabajando. Esta orden almacena 95.313 +los cambios que haya hecho al directorio actual de trabajo en su 95.314 +parche, y almacena el conjunto de cambios correspondiente que contiene 95.315 +los cambios. 95.316 + 95.317 +\begin{figure}[ht] 95.318 + \interaction{mq.tutorial.qrefresh} 95.319 + \caption{Refrescar un parche} 95.320 + \label{ex:mq:qrefresh} 95.321 +\end{figure} 95.322 + 95.323 +Puede ejecutar la orden \hgxcmd{mq}{qrefresh} tan seguido como quiera, 95.324 +y es una buena forma de ``colocar marcas'' a su trabajo. Refresque su 95.325 +parche en momentos oportunos; intente un experimento; si el 95.326 +experimento no funciona, Use \hgcmd{revert} sobre sus modificaciones 95.327 +para volver al refresco anterior. 95.328 + 95.329 +\begin{figure}[ht] 95.330 + \interaction{mq.tutorial.qrefresh2} 95.331 + \caption{Refrescar un parche muchas veces para acumular cambios} 95.332 + \label{ex:mq:qrefresh2} 95.333 +\end{figure} 95.334 + 95.335 +\subsection{Aplicar un parche tras otro y dar seguimiento} 95.336 + 95.337 +Cuando haya terminado de trabajar en un parche, o necesite trabajar en 95.338 +otro, puede usar la orden \hgxcmd{mq}{qnew} para crear un nuevo 95.339 +parche. Mercurial aplicará este parche sobre su parche anterior. 95.340 +Para un ejemplo, ver la figura~\ref{ex:mq:qnew2}. Note que el parche 95.341 +contiene los cambios en nuestro parche anterior como parte de su 95.342 +contexto (lo verá más claramente en la salida de \hgcmd{annotate}). 95.343 + 95.344 +\begin{figure}[ht] 95.345 + \interaction{mq.tutorial.qnew2} 95.346 + \caption{Aplicar un parche después del primero} 95.347 + \label{ex:mq:qnew2} 95.348 +\end{figure} 95.349 + 95.350 +Hasta ahora, con excepción de \hgxcmd{mq}{qnew} y 95.351 +\hgxcmd{mq}{qrefresh}, hemos sido cuidadosos para aplicar únicamente 95.352 +órdenes usuaales de Mercurial. De todas maneras, MQ ofrece muchos 95.353 +comandos que son más sencillos de usar cuando esté pensando acerca de 95.354 +parches, como se puede ver en la figura~\ref{ex:mq:qseries}: 95.355 + 95.356 +\begin{itemize} 95.357 +\item La orden \hgxcmd{mq}{qseries} lista cada parche del cual MQ 95.358 + tiene noticia en este repositorio, desde el más antiguo hasta el más 95.359 + nuevo (El último \emph{creado}). 95.360 +\item La orden \hgxcmd{mq}{qapplied} lista cada parche que MQ haya 95.361 + \emph{aplicado} en este repositorio, de nuevo, desde el más antiguo 95.362 + hasta el más nuevo (El aplicado más recientemente). 95.363 +\end{itemize} 95.364 + 95.365 +\begin{figure}[ht] 95.366 + \interaction{mq.tutorial.qseries} 95.367 + \caption{Entender la pila de parches con \hgxcmd{mq}{qseries} y 95.368 + \hgxcmd{mq}{qapplied}} 95.369 + \label{ex:mq:qseries} 95.370 +\end{figure} 95.371 + 95.372 +\subsection{Manipular la pila de parches} 95.373 + 95.374 +La discusión previa indicó que debe haber una diferencia entre los 95.375 +parches ``conocidos'' y ``aplicados'', y efectivamente la hay. MQ 95.376 +puede manejar un parche sin que este haya sido aplicado al 95.377 +repositorio. 95.378 + 95.379 +Un parche \emph{aplicado} tiene su correspondiente conjunto de cambios 95.380 +en el repositorio, y los efectos del parche y el conjunto de cambios 95.381 +son visibles en el directorio de trabajo. Puede deshacer la 95.382 +aplicación de un parche con la orden \hgxcmd{mq}{qpop}. MQ 95.383 +\emph{sabe acerca de}, o maneja un parche sustraído, pero el parche ya 95.384 +no tendrá un conjunto de cambios correspondientes en el repositorio, y 95.385 +el directorio de trabajo no contendrá los cambios hechos por el 95.386 +parche. La figura~\ref{fig:mq:stack} ilustra la diferencia entre 95.387 +parches aplicados y seguidos. 95.388 + 95.389 +\begin{figure}[ht] 95.390 + \centering 95.391 + \grafix{mq-stack} 95.392 + \caption{Parches aplicados y no aplicados en la pila de parches de MQ} 95.393 + \label{fig:mq:stack} 95.394 +\end{figure} 95.395 + 95.396 +Puede reaplicar un parche no aplicado o sustraído con la orden 95.397 +\hgxcmd{mq}{qpush}. Esto crea un nuevo conjunto de cambios 95.398 +correspondiente al parche, y los cambios del parche estarán presentes 95.399 +de nuevo en el directorio de trabajo. Vea ejemplos de 95.400 +\hgxcmd{mq}{qpop} y \hgxcmd{mq}{qpush} en acción en la 95.401 +figura~\ref{ex:mq:qpop}. Vea que hemos sustraído uno o dos parches, 95.402 +la salida de\hgxcmd{mq}{qseries} continúa igual, mientras que 95.403 +\hgxcmd{mq}{qapplied} ha cambiado. 95.404 + 95.405 +\begin{figure}[ht] 95.406 + \interaction{mq.tutorial.qpop} 95.407 + \caption{Modificar la pila de parches aplicados} 95.408 + \label{ex:mq:qpop} 95.409 +\end{figure} 95.410 + 95.411 +\subsection{Introducir y sustraer muchos parches} 95.412 + 95.413 +Mientras que \hgxcmd{mq}{qpush} y \hgxcmd{mq}{qpop} operan sobre un 95.414 +único parche cada vez, puede introducir y sustraer varios parches de 95.415 +una vez. La opción \hgxopt{mq}{qpush}{-a} de \hgxcmd{mq}{qpush} 95.416 +introduce todos los cambios que no hayan sido aplicados, mientras que 95.417 +la opción \hgxopt{mq}{qpop}{-a} de \hgxcmd{mq}{qpop} sustrae todos los 95.418 +cambios aplicados. (Vea la sección~\ref{sec:mq:perf} más adelante 95.419 +en la cual se explican otras formas de de introducir y sustraer varios 95.420 +cambios.) 95.421 + 95.422 +\begin{figure}[ht] 95.423 + \interaction{mq.tutorial.qpush-a} 95.424 + \caption{Pushing all unapplied patches} 95.425 + \label{ex:mq:qpush-a} 95.426 +\end{figure} 95.427 + 95.428 +\subsection{Medidas de seguridad y cómo saltarlas} 95.429 + 95.430 +Muchas órdenes MQ revisan el directorio de trabajo antes de hacer 95.431 +cualquier cosa, y fallan si encuentran alguna modificación. Lo hacen 95.432 +para garantizar que usted no pierda cambio alguno de los que haya 95.433 +hecho, pero que no hayan sido incorporados en algún parche. La 95.434 +figura~\ref{ex:mq:add} ilusta esto; la orden \hgxcmd{mq}{qnew} no 95.435 +creará un nuevo parche si hay cambios notorios, causados en este caso 95.436 +por aplicado la orden \hgcmd{add} a \filename{file3}. 95.437 + 95.438 +\begin{figure}[ht] 95.439 + \interaction{mq.tutorial.add} 95.440 + \caption{Crear un parche a la fuerza} 95.441 + \label{ex:mq:add} 95.442 +\end{figure} 95.443 + 95.444 +Las órdenes que revisan el directorio actual cuentan con una opción 95.445 +``Se lo que estoy haciendo'', que siempre está nombrada como 95.446 +\option{-f}. El significado exacto de \option{-f} depende de la 95.447 +orden. Por ejemplo, \hgcmdargs{qnew}{\hgxopt{mq}{qnew}{-f}} 95.448 +incorporarán cualquier cambio notorio en el nuevo parche que crea pero 95.449 +\hgcmdargs{qpop}{\hgxopt{mq}{qpop}{-f}} revertirá las modificaciones a 95.450 +cualquier fichero que haya sido afectado por el parche que está siendo 95.451 +sustraído. ¡Asegúrese de leer la documentación de la opción \option{-f} 95.452 +de cada comando antes de usarla! 95.453 + 95.454 +\subsection{Trabajar con varios parches a la vez} 95.455 + 95.456 +La orden \hgxcmd{mq}{qrefresh} siempre refresca el \emph{último} 95.457 +parche aplicado. Esto significa que usted puede suspender su trabajo 95.458 +en un parche (refrescándolo), sustraerlo o introducirlo para lograr 95.459 +que otro parche esté de último y trabajar en \emph{ese} parche por un 95.460 +rato. 95.461 + 95.462 +A continuación un ejemplo que ilustra cómo puede usar esta habilidad. 95.463 +Digamos que está desarrollando una nueva característica en dos 95.464 +parches. El primero es un cambio en la parte fundamental de su 95.465 +programa, y el segundo--sobre el primero---cambia la interfaz de 95.466 +usuario para usar el código que ha añadido a la parte fundamental. Si 95.467 +ve que hay un fallo en la parte fundamental mientras está trabajando 95.468 +en el parche de UI\ndt{Interfaz de Usuario, User Interface en inglés}, es fácil arreglar la parte fundamental. 95.469 +Simplemente use \hgxcmd{mq}{qrefresh} sobre el parche de la UI para 95.470 +guardar los cambios de su trabajo en progreso, y use \hgxcmd{mq}{qpop} 95.471 +para sacar sustraer el parche de la parte fundamental. Arregla el 95.472 +fallo sobre la parte fundamental, aplique \hgxcmd{mq}{qrefresh} sobre 95.473 +el parche fundamental, y aplique \hgxcmd{mq}{qpush} sobre el parche de 95.474 +UI para continuar donde había quedado. 95.475 + 95.476 +\section{Más acerca de parches} 95.477 +\label{sec:mq:adv-patch} 95.478 + 95.479 +MQ usa la orden GNU \command{patch} para aplicar los parches, por lo 95.480 +tanto es útil conocer ciertos detalles de cómo trabaja 95.481 +\command{patch}, y también acerca de los parches. 95.482 + 95.483 +\subsection{La cantidad de franjas} 95.484 + 95.485 +Si ve el encabezado de un parche, notará que la ruta al fichero tiene 95.486 +un componente adicional al principio, que no está presente en la 95.487 +ruta. Esta es una traza de cómo generaba anteriormente los parches la 95.488 +gente (algunos aún lo hacen, pero es raro con las herramientas de 95.489 +control de revisiones del actuales). 95.490 + 95.491 +Alicia desempaquetaría un comprimido, editaría sus ficheros, y querría 95.492 +crear un parche. Por lo tanto ella renombraría su directorio de 95.493 +trabajo, desempacaría el comprimido de nuevo (para lo cual necesitó el 95.494 +renombramiento), y usaría las opciones \cmdopt{diff}{-r} y 95.495 +\cmdopt{diff}{-N} de \command{diff} para generar recursivamente un 95.496 +parche entre el directorio original y el modificado. El resultado 95.497 +sería que el nombre del directorio original estaría al principio de 95.498 +toda ruta en cada encabezado de fichero, y el nombre del directorio 95.499 +modificado estaría al frente de la porción derecha de la ruta del 95.500 +fichero. 95.501 + 95.502 +Como alguien que reciba un parche de Alicia en la red podría obtener 95.503 +dos directorios, uno original y el otro modificado con exactamente los 95.504 +mismos nombres, la orden \command{patch} tiene la opción 95.505 +\cmdopt{patch}{-p} que indica la cantidad de componentes de la ruta 95.506 +a eliminar cuando se vaya a aplicar el parche. Este número se 95.507 +llama la \emph{cantidad de eliminaciones}. 95.508 + 95.509 +La opción con ``\texttt{-p1}'' significa ``elimine uno''. Si 95.510 +\command{patch} ve un nombre de fichero \filename{foo/bar/baz} en el 95.511 +encabezado del fichero, eliminará \filename{foo} y tratará de parchar 95.512 +un fichero llamado \filename{bar/baz}. (Hablando estrictamente, la 95.513 +cantidad de eliminaciones se refiere a la cantidad de \emph{separadores de 95.514 + ruta} (y los componentes que vayan con ellos) a eliminar. Si el 95.515 +contador es uno volverá \filename{foo/bar} en \filename{bar}, pero 95.516 +\filename{/foo/bar} (note la barra extra) en \filename{foo/bar}.) 95.517 + 95.518 +La cantidad a eliminar``estándar'' para parches es uno; casi todos los 95.519 +parches contienen un componente inicial de la ruta que necesita ser 95.520 +eliminado. La orden \hgcmd{diff} de Mercurial genera nombres de ruta 95.521 +de esta forma, y la orden \hgcmd{import} y MQ esperan parches que 95.522 +tengan a uno como cuenta de eliminaciones. 95.523 + 95.524 +Si recibe un parche de alguien de quien desea adicionar adicionar a su 95.525 +cola de parches, y el parche necesita una cuenta de eliminación que no 95.526 +sea uno, no podrá aplicar \hgxcmd{mq}{qimport} en primera medida, 95.527 +porque \hgxcmd{mq}{qimport} no tiene todavía una opción \texttt{-p} 95.528 +option (ver~\bug{311}). Lo mejor que puede hacer es aplicar 95.529 +\hgxcmd{mq}{qnew} por su cuenta, y después usar \cmdargs{patch}{-p\emph{N}} 95.530 +para aplicar tal parche, seguido de \hgcmd{addremove} para tener en 95.531 +cuenta cualquier fichero adicionado o eliminado por el parche, seguido 95.532 +de \hgxcmd{mq}{qrefresh}. Esta complejidad puede ser innecesaria; 95.533 +consulte~\bug{311} para más información. 95.534 + 95.535 +\subsection{Estrategias para aplicar parches} 95.536 + 95.537 +Cuando \command{patch} aplica un trozo, intenta varias estrategias 95.538 +sucesivas que decrecen en precisión para intentar aplicarlo. Esta 95.539 +técnica de pruebas y error aveces permite que un parche que fue 95.540 +generado contra una versión anterior de un fichero, sea aplicada sobre 95.541 +una versión más nueva del mismo. 95.542 + 95.543 +Primero \command{patch} intenta una correspondencia perfecta donde los 95.544 +números de línea, el contexto y el texto a modificar deben coincidir 95.545 +perfectamente. Si no lo logra, intenta encontrar una correspondencia 95.546 +exacta del contexto, sin tener en cuenta el número de línea. Si es 95.547 +exitoso, imprime una línea indicando que el trozo fue aplicado, pero a 95.548 +un \emph{corrimiento} del número de línea original. 95.549 + 95.550 +Si falla la correspondencia por contexto, \command{patch} elimina la 95.551 +primera y la última línea del contexto, e intenta una correspondencia 95.552 +\emph{reducida} del contexto. Si el trozo con contexto reducido es 95.553 +exitoso, imprime un mensaje indicando que aplicó el trozo con un 95.554 +\emph{factor difuso} (el número después del factor difuso indica 95.555 +cuántas líneas de contexto \command{patch} tuvo que eliminar antes de 95.556 +aplicar el parche). 95.557 + 95.558 +Cuando ninguna de estas técnicas funciona, \command{patch} imprime un 95.559 +mensaje indicando que el trozo en cuestión se desechó. Almacena los 95.560 +trozos desechados (también llamados ``descartados'') en un fichero con 95.561 +el mismo nombre, y la extensión \sfilename{.rej} añadida. También 95.562 +almacena una copia igual al fichero original con la extensión 95.563 +\sfilename{.orig}; la copia del fichero sin extensión contendrá 95.564 +cualquier cambio hecho por los trozos que \emph{sí} se aplicaron sin 95.565 +problema. Si usted tiene un parche que modifica \filename{foo} con 95.566 +seis trozos, y uno de ellos falla al aplicarse, tendrá : un fichero 95.567 +original \filename{foo.orig}, un fichero \filename{foo.rej} que 95.568 +contiene el trozo, y \filename{foo}, que contiene los cambios que se 95.569 +aplicaron por los cinco trozos exitosos. 95.570 + 95.571 +\subsection{Algunos detalles de la representación de parches} 95.572 + 95.573 +Hay ciertas cosas útiles por saber acerca de cómo trabaja 95.574 +\command{patch} con los ficheros: 95.575 +\begin{itemize} 95.576 +\item Debería ser obvio que \command{patch} no puede manipular 95.577 + ficheros binarios. 95.578 +\item No se preocupa por el bit ejecutable; crea ficheros nuevos en 95.579 + modo lectura, pero no ejecutable. 95.580 +\item \command{patch} intenta eliminar un fichero como una diferencia 95.581 + entre el fichero a eliminar y un fichero vacío. Y por lo tanto su 95.582 + idea de ``Borré este fichero'' debería pensarse como ``toda línea de 95.583 + este fichero fue eliminada'' en un parche. 95.584 +\item Trata la adición de un fichero como un diff entre un fichero 95.585 + vacío y el fichero a ser adicionado. Por lo tanto en un parche su 95.586 + idea de ``Añadí este fichero'' se vería como ``toda línea de este 95.587 + fichero fue añadida''. 95.588 +\item Trata el renombramiento de un fichero como la eliminación del 95.589 + nombre anterior y la adición del nuevo nombre. Esto significa que 95.590 + los ficheros renombrados dejan un rastro grande en los parches. 95.591 + (Tenga en cuenta que Mercurial no trata de inferir cuando los 95.592 + ficheros han sido renombrados o copiados en un parche en este 95.593 + momento.) 95.594 +\item \command{patch} no puede representar ficheros vacíos, por lo 95.595 + tanto no puede usar un parche para representar la noción ``Añadí 95.596 + este fichero vacío al árbol''. 95.597 +\end{itemize} 95.598 +\subsection{Cuidado con los difusos} 95.599 + 95.600 +Cuando aplique un trozo con un corrimiento, o con un factor difuso, 95.601 +aveces será taotalmente exitoso, tales técnicas inexactas dejan 95.602 +claramente la posibilidad de corromper el fichero parchado. Los casos 95.603 +más típicos involucran aplicar un parche dos veces o en un sitio 95.604 +incorrecto del fichero. Si \command{patch} o \hgxcmd{mq}{qpush} llegan 95.605 +a mencionar un corrimiento o un factor difuso, debería asegurarse que 95.606 +los ficheros modificados estén correctos después del suceso. 95.607 + 95.608 +Casi siempre es buena idea refrescar un parche que fue aplicado con un 95.609 +corrimiento o un factor difuso; refrescar el parche genera nueva 95.610 +información de contexto que permitirá aplicarlo limpiamente. Digo 95.611 +``casi siempre,'' no ``siempre'', puesto que en ciertas ocasiones 95.612 +refrescar un parche lo hará fallar frente a una revisión diferente del 95.613 +fichero. En algunos casos, como por ejemplo, cuando usted está 95.614 +manteniendo un parche que debe estar encima de múltiples revisiones de 95.615 +un árbol de fuentes, es aceptable tener un parche aplicado algo 95.616 +difuso, siempre que haya verificado los resultados del proceso de 95.617 +parchar. 95.618 + 95.619 +\subsection{Manejo de descartes} 95.620 + 95.621 +Si \hgxcmd{mq}{qpush} falla al aplicar un parche, mostrará un texto de 95.622 +error y saldrá. Si ha dejado ficheros \sfilename{.rej}, es mejor 95.623 +arreglar los trozos descartados antes de introducir parches 95.624 +adicionales o hacer cualquier otra cosa. 95.625 + 95.626 +Si su parche \emph{solía} aplicarse limpiamente, y ya no lo hace 95.627 +porque ha cambiado código subyacente en el cual se basa su parche, las 95.628 +Colas de Mercurial pueden ayudar; consulte la sección~\ref{sec:mq:merge}. 95.629 + 95.630 +Desafortunadamente, no hay grandes técnicas para tratar los trozos 95.631 +descartados. Casi siempre deberá consultar el fichero 95.632 +\sfilename{.rej} y editar el fichero objetivo, aplicando los trozos 95.633 +descartados a mano. 95.634 + 95.635 +Si es aventurero, Neil Brown, un hacker del núcleo Linux, escribió una 95.636 +herramienta llamada \command{wiggle}~\cite{web:wiggle}, que es más 95.637 +vigorosa que \command{patch} en su intento de hacer que se aplique un 95.638 +parche. 95.639 + 95.640 +Otro hacker del nucleo Linux, Chris Mason (el autor de las Colas de 95.641 +Mercurial), escribió una herramienta similar llamada 95.642 +\command{mpatch}~\cite{web:mpatch}, que sigue una aproximación 95.643 +sencilla para automatizar la aplicación de trozos descartados por 95.644 +\command{patch}. La orden \command{mpatch} puede ayudar con cuatro 95.645 +razones comunes por las cuales un parche ha sido descartado: 95.646 + 95.647 +\begin{itemize} 95.648 +\item El contexto en la mitad de un trozo ha cambiado. 95.649 +\item Un trozo ha perdido cierto contexto al principio o al final. 95.650 +\item Un trozo largo podría aplicarse mejor---por completo o una 95.651 + parte---si estaba cortado en trozos más pequeños. 95.652 +\item Un trozo remueve líneas con contenido ligeramente diferente que 95.653 + aquellas que están presentes en el fichero. 95.654 +\end{itemize} 95.655 + 95.656 +Si usted usa \command{wiggle} o \command{mpatch}, debería ser 95.657 +doblemente cuidadoso al revisar sus resultados cuando haya terminado. 95.658 +De hecho, \command{mpatch} refuerza este método de revisar por partida 95.659 +doble su salida, dejándolo a usted en un programa de fusión cuando la 95.660 +herramienta haya terminado su trabajo, de tal forma que usted pueda 95.661 +verificar lo que ha hecho y pueda terminar de aplicar cualquier fusión 95.662 +faltante. 95.663 + 95.664 +\section{maximizar el rendimiento de MQ} 95.665 +\label{sec:mq:perf} 95.666 + 95.667 +MQ es muy eficiente al tratar con una gran cantidad de parches. Corrí 95.668 +unos experimentos de desempeño a mediados del 2006 para una charla que 95.669 +dí en la conferencia EuroPython 2006~\cite{web:europython}. Empleé la 95.670 +serie de parches para el núcleo Linux 2.6.17-mm1, que contaba con 1.738 95.671 +parches. Los apliqué sobre un repositorio del núcleo de Linux con 95.672 +todas las 27.472 revisiones entre 2.6.12-rc2 y 2.6.17. 95.673 + 95.674 +En mi portátil antiguo y lento, logré aplicar 95.675 +\hgcmdargs{qpush}{\hgxopt{mq}{qpush}{-a}} a los 1.738 parches en 3.5 95.676 +minutos, y \hgcmdargs{qpop}{\hgxopt{mq}{qpop}{-a}} en 30 segundos. 95.677 +(En un portátil más nuevo, el tiempo para introducir todos los 95.678 +parches, se logró en menos de dos minutos.) Apliqué 95.679 +\hgxcmd{mq}{qrefresh} sobre uno de los parches más grandes (que hizo 95.680 +22.779 líneas de cambios en 287 ficheros) en 6,6 segundos. 95.681 + 95.682 +Claramente, MQ funciona adecuadamente en árboles grandes, y además hay 95.683 +unos trucos que pueden emplearse para obtener el máximo desempeño. 95.684 + 95.685 +En primer lugar, trate de hacer ``en lote'' las operaciones. Cada vez 95.686 +que ejecute \hgxcmd{mq}{qpush} o \hgxcmd{mq}{qpop}, tales órdenes 95.687 +revisan el directorio de trabajo para asegurarse de que usted no ha 95.688 +hecho cambios y ha olvidado ejecutar \hgxcmd{mq}{qrefresh}. En un 95.689 +árbol pequeño, el tiempo de esta revisión puede ser mínimo, Pero en 95.690 +un árbol mediano (con decenas de miles de ficheros), puede tomar un 95.691 +segundo o más. 95.692 + 95.693 +Las órdenes \hgxcmd{mq}{qpush} y \hgxcmd{mq}{qpop} le permiten 95.694 +introducir o sustraer varios parches en una operación. Puede 95.695 +identificar el ``parche destino'' que desee. Cuando aplique 95.696 +\hgxcmd{mq}{qpush} con un destino, introducirá tantos parches como sea 95.697 +necesario hasta que el especificado esté en el tope de la pila. 95.698 +Cuando emplee \hgxcmd{mq}{qpop} con un destino, MQ sustraerá parches 95.699 +hasta que el parche destino esté en el tope. 95.700 + 95.701 +Puede identificar un parche destino con el nombre del parche o con el 95.702 +número. Si se refiere al número, los parches se contarán desde cero; 95.703 +esto significa que el primer parche es cero, el segundo es uno y así 95.704 +sucesivamente. 95.705 + 95.706 +\section{Actualiar los parches cuando el código cambia} 95.707 +\label{sec:mq:merge} 95.708 + 95.709 +Es común contar con una pila de parches sobre un repositorio que usted 95.710 +no modifica directamente. Si está trabajando en cambios de código de 95.711 +otros, o en una característica que tarda bastante en desarrollarse 95.712 +comparada con la tasa de cambio del código sobre la cual se está 95.713 +trabajando, necesitará sincronizarse con el código, y ajustar 95.714 +cualquier trozo en sus parches que ya no estén al día. A esto se le 95.715 +llama hacer \emph{rebase} a su serie de parches. 95.716 + 95.717 +La vía más sencilla de hacerlo es con \hgcmdargs{qpop}{\hgxopt{mq}{qpop}{-a}} 95.718 +sobre sus parches, después hacer \hgcmd{pull} de los cambios en el 95.719 +repositorio, y finalmente hacer 95.720 +\hgcmdargs{qpush}{\hgxopt{mq}{qpop}{-a}} con sus parches de nuevo. MQ 95.721 +dejará de de introducir parches siempre que llegue a un parche que no se pueda 95.722 +aplicar debido a un conflicto, permitiéndole a usted arreglarlo, 95.723 +aplicar \hgxcmd{mq}{qrefresh} al parche afectado y continuar 95.724 +introduciendo hasta que haya arreglado la pila completa. 95.725 + 95.726 +Esta aproximación es sencilla y funciona bien si no espera cambios en 95.727 +el código original que afecte en gran medida los parches que usted 95.728 +esté aplicando. Si su pila de parches toca código que es modificado 95.729 +frecuentemente o de forma invasiva sobre el código subyacente, 95.730 +arreglar trozos manualmente se vuelve desgastante. 95.731 + 95.732 +Es posible automatizar de forma parcial el proceso de rebase. Si sus 95.733 +parches se aplican limpiamente sobre algunas revisiones del 95.734 +repositorio subyacente, MQ puede usar esta información para ayudarle a 95.735 +a resolver conflictos entre sus parches y una revisión distinta. 95.736 + 95.737 +El proceso resulta un poco complejo: 95.738 +\begin{enumerate} 95.739 +\item Para comenzar, haga \hgcmdargs{qpush}{-a} sobre todos los 95.740 + parches que usted sepa se aplican limpiamente. 95.741 +\item Guarde una copia de seguridad de su directorio de parches con 95.742 + \hgcmdargs{qsave}{\hgxopt{mq}{qsave}{-e} \hgxopt{mq}{qsave}{-c}}. 95.743 + Esto imprime el nombre del directorio en el cual se han guardado los 95.744 + parches. Guardará los parches en un directorio llamado 95.745 + \sdirname{.hg/patches.\emph{N}}, donde \texttt{\emph{N}} es un 95.746 + entero pequeño. También consigna un ``conjunto de cambios de 95.747 + seguridad'' sobre sus parches aplicados; esto es para mantener el 95.748 + histórico, y guarda los estados de los ficheros \sfilename{series} 95.749 + y \sfilename{status}. 95.750 +\item Use \hgcmd{pull} para traer los nuevos cambios en el repositorio 95.751 + subyacente. (No ejecute \hgcmdargs{pull}{-u}; vea más adelante por qué.) 95.752 +\item Actualice a la nueva revisión punta con 95.753 + \hgcmdargs{update}{\hgopt{update}{-C}} para sobreescribir los 95.754 + parches que haya introducido. 95.755 +\item Fusione todos los parches con \hgcmdargs{qpush}{\hgxopt{mq}{qpush}{-m} 95.756 + \hgxopt{mq}{qpush}{-a}}. La opción \hgxopt{mq}{qpush}{-m} de \hgxcmd{mq}{qpush} 95.757 + le indica a MQ que haga una fusión que involucra tres fuentes si el 95.758 + parche falla al aplicarse. 95.759 +\end{enumerate} 95.760 + 95.761 +Durante el \hgcmdargs{qpush}{\hgxopt{mq}{qpush}{-m}}, cada parche en 95.762 +el fichero \sfilename{series} se aplica normalmente. Si un parche se 95.763 +aplica difusamente o se niea a aplicarse, MQ consulta la cola que 95.764 +usted guardó con \hgxcmd{mq}{qsave}, y aplica una fusión de tres con 95.765 +el correspondiente conjunto de cambios. Esta fusión usa la maquinaria 95.766 +de Mercurial, por lo tanto puede mostrar una herramienta de fusión GUI 95.767 +para ayudarle a resolver los problemas. 95.768 + 95.769 +Cuando termine de resolver los efectos de un parche, MQ refrescará su 95.770 +parche basado en el resultado de la fusión. 95.771 + 95.772 +Al final de este proceso, su repositorio tendrá una cabeza extra de la 95.773 +antigua cola de parches, y una copia de la cola de parches anterio 95.774 +estará en \sdirname{.hg/patches.\emph{N}}. Puede eliminar la cabeza 95.775 +extra con \hgcmdargs{qpop}{\hgxopt{mq}{qpop}{-a} \hgxopt{mq}{qpop}{-n} patches.\emph{N}} 95.776 +o \hgcmd{strip}. Puede eliminar \sdirname{.hg/patches.\emph{N}} una 95.777 +vez que esté seguro de que no lo necesita más como copia de seguridad. 95.778 + 95.779 +\section{Identificar parches} 95.780 + 95.781 +Las órdenes de MQ le permiten trabajar refiriéndose al nombre del 95.782 +parche o al número. Es obvio hacerlo por el nombre; por ejemplo se 95.783 +pasa el nombre \filename{foo.patch} a \hgxcmd{mq}{qpush}, que 95.784 +introducirá los parches hasta que \filename{foo.patch} se aplique. 95.785 + 95.786 +Para hacerlo más corto, puede referirse a un parche con un nombre y un 95.787 +corrimiento de número; por ejemplo, \texttt{foo.patch-2} significa 95.788 +``dos parches antes de \texttt{foo.patch}'', mientras que 95.789 +\texttt{bar.patch+4} significa ``cuatro parches después de \texttt{bar.patch}''. 95.790 + 95.791 +Referirse a un parche por su índice no es muy diferente. El primer 95.792 +parche que se imprime en la salida de \hgxcmd{mq}{qseries} es el 95.793 +parche cero (si, es el primero en los sistemas que comienzan su conteo 95.794 +en cero); el segundo parche es uno y así sucesivamente. 95.795 + 95.796 +MQ facilita el trabajo cuando está usando órdenes normales de 95.797 +Mercurial. Cada comando que acepte Identificadores de conjuntos de 95.798 +cambios también aceptará el nombre de un parche aplicado. MQ aumenta 95.799 +las etiquetas normalmente en el repositorio con un distintivo para cada 95.800 +parche aplicado. Adicionalmente, las etiquetas especiales \index{tags!special tag 95.801 + names!\texttt{qbase}}\texttt{qbase} y \index{tags!special tag 95.802 + names!\texttt{qtip}}\texttt{qtip} identifican los parches 95.803 +``primero'' y último, respectivamente. 95.804 + 95.805 +Junto con las capacidades de Mercurial para etiquetar, estas adiciones 95.806 +hacen que trabajar con parches sea muy sencillo. 95.807 +\begin{itemize} 95.808 +\item ¿Desea enviar una bomba de parches a una lista de correo con los 95.809 + últimos cambios que ha hecho? 95.810 + \begin{codesample4} 95.811 + hg email qbase:qtip 95.812 + \end{codesample4} 95.813 + (¿No sabe qué es una ``bomba de parches''? Consulte la 95.814 + sección~\ref{sec:hgext:patchbomb}.) 95.815 +\item ¿Desea ver todos los parches desde que se aplicó 95.816 + \texttt{foo.patch} sobre los ficheros de un subdirectorio en su 95.817 + árbol? 95.818 + \begin{codesample4} 95.819 + hg log -r foo.patch:qtip \emph{subdir} 95.820 + \end{codesample4} 95.821 +\end{itemize} 95.822 + 95.823 +Dado que MQ nombra los parches disponibles al resto de Mercurial con 95.824 +su maquinaria de etiquetas interna, usted no necesita teclear el 95.825 +nombre completo de un parche cuando desea identificarlo por su nombre. 95.826 + 95.827 +\begin{figure}[ht] 95.828 + \interaction{mq.id.output} 95.829 + \caption{Uso de las características de etiquetamiento al trabajar 95.830 + con MQ} 95.831 + \label{ex:mq:id} 95.832 +\end{figure} 95.833 + 95.834 +Otra consecuencia deseable al representar los nombres de parches como 95.835 +etiquetas es que cuando ejecute la orden \hgcmd{log}, desplegará el 95.836 +nombre del parche como una etiqueta, usualmente con la salida normal. 95.837 +Esto facilita distinguir visualmente los parches aplicados de las 95.838 +revisiones ``normales''. La figura~\ref{ex:mq:id} muestra algunos 95.839 +comandos usuales de Mercurial al trabajar con parches. 95.840 + 95.841 +\section{Otra información útil} 95.842 + 95.843 +Hay una cantidad de aspectos que hacen que el uso de MQ no representen 95.844 +secciones en sí mismas, pero de los cuales es bueno estar 95.845 +enterado. Los presentamos en aquí: 95.846 + 95.847 +\begin{itemize} 95.848 +\item Usualmente cuando hace \hgxcmd{mq}{qpop} a un parche y vuelve a 95.849 + hacerle \hgxcmd{mq}{qpush}, el conjunto de cambios que representa el 95.850 + parche después de introducir/sustraer tendrá una \emph{identidad 95.851 + distinta} que aquella que representaba el conjunto de cambios 95.852 + anteriormente. Consulte la secctión~\ref{sec:mqref:cmd:qpush} para 95.853 + obtener información del por qué de esto. 95.854 +\item No es una buena idea aplicar \hgcmd{merge} de cambios de otra 95.855 + rama con un conjunto de cambios de parches, por lo menos si desea 95.856 + mantener la ``información de parches'' de ese conjunto de cambios y 95.857 + los conjuntos de cambios que se encuentran por debajo en la pila de 95.858 + parches. Si intenta hacerlo, parecerá que ha sido exitoso, pero MQ 95.859 + se confundirá. 95.860 +\end{itemize} 95.861 + 95.862 +\section{Administrar parches en un repositorio} 95.863 +\label{sec:mq:repo} 95.864 + 95.865 +Dado que el directorio \sdirname{.hg/patches} de MQ reside fuera del 95.866 +repositorio de trabajo de Mercurial, el repositorio ``subyacente'' de 95.867 +Mercurial no sabe nada acerca de la administración o presencia de 95.868 +parches. 95.869 + 95.870 +Esto presenta la interesante posibilidad de administrar los contenidos 95.871 +del directorio de parches como un repositorio de Mercurial por su 95.872 +cuenta. Puede ser una forma útil de trabajar. Por ejemplo, puede 95.873 +trabajar en un parche por un rato, hacerle \hgxcmd{mq}{qrefresh} y 95.874 +después hacer \hgcmd{commit} al estado actual del parche. Esto le 95.875 +permite ``devolverse'' a esa versión del parche posteriormente. 95.876 + 95.877 +Puede también compartir diferentes versiones de la misma pila de 95.878 +parches entre varios repositorios subyacentes. Uso esto cuando estoy 95.879 +desarrollando una característica del núcleo Linux. Tengo una copia 95.880 +original de las fuentes del núcleo para varias arquitecturas, y cloné 95.881 +un rpositorio en cada una que contiene los parches en los cuales 95.882 +estoy trabajando. Cuando quiero probar un cambio en una arquitectura 95.883 +diferente, introduzco mis parches actuales al repositorio de parches 95.884 +asociado con el árbol del kernel, sustraigo e introduzco todos mis 95.885 +parches, armo y pruebo el núcleo. 95.886 + 95.887 +Llevar los parches en un repositorio permite que varios 95.888 +desarrolladores puedan trabajar en la misma serie de parches sin 95.889 +sobreponerse, todo sobre la fuente base subyacente que pueden o no 95.890 +controlar. 95.891 + 95.892 +\subsection{Soporte de MQ para repositorios de parches} 95.893 + 95.894 +MQ le ayuda a trabajar con el directorio \sdirname{.hg/patches} como 95.895 +un repositorio; cuando usted prepara un repositorio para trabajar con 95.896 +parches usando \hgxcmd{mq}{qinit}, puede pasarle la opción 95.897 +\hgxopt{mq}{qinit}{-c} para que se cree el directorio 95.898 +\sdirname{.hg/patches} como un repositorio de Mercurial. 95.899 + 95.900 +\begin{note} 95.901 + Si olvida usar la opción \hgxopt{mq}{qinit}{-c} option, puede ir al 95.902 + directorio \sdirname{.hg/patches} en cualquier momento y ejecutar 95.903 + \hgcmd{init}. No olvide añadir una entrada en el fichero 95.904 + \sfilename{status} del fichero \sfilename{.hgignore}, a pesar de que 95.905 + (\hgcmdargs{qinit}{\hgxopt{mq}{qinit}{-c}} hace estodo de forma 95.906 + automática para usted); usted \emph{seguro} no quiere administrar el 95.907 + fichero \sfilename{status}. 95.908 +\end{note} 95.909 + 95.910 +MQ nota convenientemente que el directorio \dirname{.hg/patches} 95.911 +es un repositorio, hará \hgcmd{add} automáticamente a cada parche que 95.912 +usted cree e importe. 95.913 + 95.914 +MQ provee una orden corta, \hgxcmd{mq}{qcommit}, que ejecuta 95.915 +\hgcmd{commit} en el directorio \sdirname{.hg/patches}. Lo que ahorra 95.916 +tecleo recurrente. 95.917 + 95.918 +Finalmente, para administrar convenientemente el directorio de 95.919 +parches, puede definir el alias \command{mq} en sistemas Unix. Por 95.920 +ejemplo, en sistemas Linux con el intérprete \command{bash}, puede 95.921 +incluir el siguiente recorte de código\ndt{snippet} en su fichero 95.922 +\tildefile{.bashrc}. 95.923 + 95.924 +\begin{codesample2} 95.925 + alias mq=`hg -R \$(hg root)/.hg/patches' 95.926 +\end{codesample2} 95.927 + 95.928 +Puede aplicar las órdenes de la forma \cmdargs{mq}{pull} al 95.929 +repositorio principal. 95.930 + 95.931 +\subsection{Detalles a tener en cuenta} 95.932 + 95.933 +El soporte de MQ para trabajar con un repositorio de parches es 95.934 +limitado en ciertos aspectos: 95.935 + 95.936 +MQ no puede detectar automáticamente los cambios que haga al 95.937 +directorio de parches. Si aplica \hgcmd{pull}, edita manualmente, o 95.938 +hace \hgcmd{update} a los parches o el fichero \sfilename{series}, 95.939 +tendrá que aplicar \hgcmdargs{qpop}{\hgxopt{mq}{qpop}{-a}} y después 95.940 +\hgcmdargs{qpush}{\hgxopt{mq}{qpush}{-a}} en el repositorio subyacente 95.941 +para que los cambios se reflejen allí. Si olvida hacerlo, puede 95.942 +confundir a MQ en cuanto a qué parches se han aplicado. 95.943 + 95.944 +\section{Otras herramientas para trabajar con parches} 95.945 +\label{sec:mq:tools} 95.946 + 95.947 +Cuando haya trabajado por cierto tiempo con parches, deseará 95.948 +herramientas que le ayuden a entender y manipular los parches con los 95.949 +que esté tratando. 95.950 + 95.951 +La orden \command{diffstat}~\cite{web:diffstat} genera un histograma 95.952 +de modificaciones hechas a cada fichero en un parche. Provee una 95.953 +interesante forma de ``dar un vistazo'' al parche---qué ficheros 95.954 +afecta, y cuántos cambios introduce a cada fichero y en total. (Me ha 95.955 +parecido interesante usar la opción \cmdopt{diffstat}{-p} de 95.956 +\command{diffstat}, puesto que de otra forma intentará hacer cosas 95.957 +inteligentes con prefijos de ficheros que terminan confundiéndome.) 95.958 + 95.959 +\begin{figure}[ht] 95.960 + \interaction{mq.tools.tools} 95.961 + \caption{Las órdenes \command{diffstat}, \command{filterdiff}, y \command{lsdiff}} 95.962 + \label{ex:mq:tools} 95.963 +\end{figure} 95.964 + 95.965 +El paquete \package{patchutils}~\cite{web:patchutils} es 95.966 +invaluable. Provee un conjunto de pequeñas utilidades que siguen la 95.967 +``filosofía Unix''; cada una hace una cosa muy bien hecha a un 95.968 +parche. La orden \package{patchutils} que más uso es 95.969 +\command{filterdiff}, que extrae subconjuntos de un fichero de 95.970 +parche. Por ejemplo, dado un parche que modifica centenas de ficheros 95.971 +en docenas de directorios, una única invocación de 95.972 +\command{filterdiff} puede generear un parche más pequeño que 95.973 +solamente toca aquellos ficheros con un patrón. Puede ver otro 95.974 +ejemplo en la sección~\ref{mq-collab:tips:interdiff}. 95.975 + 95.976 +\section{Buenas prácticas de trabajo con parches} 95.977 + 95.978 +En caso de que esté trabajando en una serie de parches para enviar a 95.979 +un proyecto de software libre o de fuentes abiertas, o en una serie 95.980 +que desea tratar como un conjunto de cambios regular, cuando haya 95.981 +terminado, puede usar técnicas sencillas para mantener su trabajo bien 95.982 +organizado. 95.983 + 95.984 +De nombres descriptivos a sus parches. Un buen nombre para un parche 95.985 +podría ser \filename{rework-device-alloc.patch}, porque da de forma 95.986 +inmediata una pista del propósito del parche. Los nombres largos no 95.987 +deben ser un problema; no los estará tecleando repetidamente, pero 95.988 +\emph{estará} ejecutando regularmente órdenes como 95.989 +\hgxcmd{mq}{qapplied} y \hgxcmd{mq}{qtop}. Los nombres adecuados son 95.990 +especialmente importantes cuando tiene bastantes parches con los 95.991 +cuales trabajar, o si está trabajando en diferentes tareas y sus 95.992 +parches toman solamente una porción de su atención. 95.993 + 95.994 +Tenga en cuenta en qué parche está trabajando. Use la orden \hgxcmd{mq}{qtop} 95.995 +para dar un vistazo al texto de sus parches frecuentemente---por 95.996 +ejemplo, use \hgcmdargs{tip}{\hgopt{tip}{-p}})---para asegurarse en 95.997 +dónde está ubicado. En distintas oportunidades me sucedió que apliqué 95.998 +\hgxcmd{mq}{qrefresh} a un parche distinto al que deseaba hacerlo, y 95.999 +usualmente es complejo migrar los cambios al parche correcto después 95.1000 +de haberlo hecho mal. 95.1001 + 95.1002 +Por este motivo, vale la pena invertir ese poco tiempo para aprender 95.1003 +cómo usar otras herramientas que describí en la 95.1004 +sección~\ref{sec:mq:tools}, particularmente \command{diffstat} y 95.1005 +\command{filterdiff}. La primera le dará una idea de qué cambios está 95.1006 +haciendo su parche, mientras que la segunda permite seleccionar trozos 95.1007 +de un parche para colocarlos en otro. 95.1008 + 95.1009 +\section{Recetas de MQ} 95.1010 + 95.1011 +\subsection{Administrar parches ``triviales''} 95.1012 + 95.1013 +Puesto que colocar ficheros en un repositorio de Mercurial es tan 95.1014 +sencillo, tiene bastante sentido administrar parches de esta forma 95.1015 +incluso si desea hacer algunos cambios al paquete de ficheros que 95.1016 +descargó. 95.1017 + 95.1018 +Para comenzar a descargar y desempaqueter un paquete de ficheros, y 95.1019 +volverlo en un repositorio de Mercurial: 95.1020 +\interaction{mq.tarball.download} 95.1021 + 95.1022 +Continue creando una pila de parches y haga sus cambios. 95.1023 +\interaction{mq.tarball.qinit} 95.1024 + 95.1025 +Digamos que pasan unas semanas o meses, y el autor del paquete libera 95.1026 +una nueva versión. Primero se traen sus cambios al repositorio. 95.1027 +\interaction{mq.tarball.newsource} 95.1028 +La porción que comienza con \hgcmd{locate} mostrada más arriba, borra 95.1029 +todos los ficheros en el directorio de trabajo, así que la opción 95.1030 +\hgopt{commit}{--addremove} de \hgcmd{commit} puede indicar qué 95.1031 +ficheros se han eliminado en la nueva versión del árbol de fuentes. 95.1032 + 95.1033 +Finalmente, puede aplicar sus parches encima del nuevo árbol de fuentes 95.1034 +\interaction{mq.tarball.repush} 95.1035 + 95.1036 +\subsection{Combinar parches completos} 95.1037 +\label{sec:mq:combine} 95.1038 + 95.1039 +MQ provee la orden \hgxcmd{mq}{qfold} que le permite combinar parches 95.1040 +enteros. Se ``integran''\ndt{fold} los parches que usted nombre, en 95.1041 +el orden que especifique, en el último parche aplicado, y concatena 95.1042 +sus descripciones al final de su descripción. Deberá sustraer los 95.1043 +cambios para poder integrarlos. 95.1044 + 95.1045 +El orden en el que integre los parches importa. Si el parche 95.1046 +últimamente aplicado es \texttt{foo}, e integra \hgxcmd{mq}{qfold} \texttt{bar} y 95.1047 +\texttt{quux} en él, terminará con un parche que tiene el mismo efecto 95.1048 +que si hubiera aplicado primero \texttt{foo}, y después \texttt{bar}, 95.1049 +seguido de \texttt{quux}. 95.1050 + 95.1051 +\subsection{Fusionar una porción de un parche dentro de otro} 95.1052 + 95.1053 +Fusionar \emph{partes} de un parche dentro de otro es más complejo que 95.1054 +combinar completamente dos parches. 95.1055 + 95.1056 +Si desea mover cambios de ficheros completos, puede usar las opciones 95.1057 +\command{filterdiff}'s \cmdopt{filterdiff}{-i} y 95.1058 +\cmdopt{filterdiff}{-x} para elegir las modificaciones remover de un 95.1059 +parche, concatenar su salida al final del parche donde desea 95.1060 +fusionarlo. Usualmente no necesitará modificar el parche del cuál ha 95.1061 +fusionado los cambios. En cambio, MQ reportará que hay unos trozos 95.1062 +que se han desechado cuando usted aplique \hgxcmd{mq}{qpush} (de los 95.1063 +trozos que haya movido al otro parche), y puede sencillamente aplicar 95.1064 +\hgxcmd{mq}{qrefresh} para eliminar los trozos replicados. 95.1065 + 95.1066 +Si tiene un parche que tiene varios trozos que modifican un fichero, y 95.1067 +desea mover solamente unos de ellos, el trabajo es un poco más 95.1068 +enredado, pero puede automatizarlo parcialmente. Use 95.1069 +\cmdargs{lsdiff}{-nvv} para imprimir algunos metadatos del parche. 95.1070 +\interaction{mq.tools.lsdiff} 95.1071 + 95.1072 +Esta orden imprime tres clases diferentes de números: 95.1073 +\begin{itemize} 95.1074 +\item (en la primera columna) un \emph{número de fichero} para 95.1075 + identificar cada fichero modificado en el parche; 95.1076 +\item (En la siguiente línea, indentado) el número de línea dentro de 95.1077 + un fichero modificado donde comienza el trozo; y 95.1078 +\item (en la misma línea) un \emph{número de trozo} que identifica el 95.1079 + trozo. 95.1080 +\end{itemize} 95.1081 + 95.1082 +Tendrá que hacer una inspección visual, y leer el parche para 95.1083 +identificar los números de fichero y trozo que desea, pero puede pasar 95.1084 +posteriormente a las opciones \cmdopt{filterdiff}{--files} y 95.1085 +\cmdopt{filterdiff}{--hunks} de \command{filterdiff}, para seleccionar 95.1086 +exactamente el fichero y el trozo que desea extraer. 95.1087 + 95.1088 +Cuando tenga el trozo, puede concatenarlo al final de su parche 95.1089 +objetivo y continuar como en la sección~\ref{sec:mq:combine}. 95.1090 + 95.1091 +\section{Diferencias entre quilt y MQ} 95.1092 + 95.1093 +Si le es familiar quilt, MQ provee un conjunto similar de órdenes. Hay 95.1094 +algunas diferencias en cómo funcionan. 95.1095 + 95.1096 +Debe haber notado que la mayoría de comandos de quilt tienen su 95.1097 +contraparte en MQ, que simplemente comienzan con ``\texttt{q}''. Las 95.1098 +excepciones son las órdenes \texttt{add} y \texttt{remove} de quilt, 95.1099 +que realmente son las órdenes \hgcmd{add} y \hgcmd{remove} de 95.1100 +Mercurial. No hay un equivalente en MQ para la orden 95.1101 +\texttt{edit} de quilt. 95.1102 + 95.1103 +%%% Local Variables: 95.1104 +%%% mode: latex 95.1105 +%%% TeX-master: "00book" 95.1106 +%%% End:
96.1 Binary file es/note.png has changed
97.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 97.2 +++ b/es/preface.tex Thu Jan 29 22:00:07 2009 -0800 97.3 @@ -0,0 +1,74 @@ 97.4 +\chapter*{Prefacio} 97.5 +\addcontentsline{toc}{chapter}{Prefacio} 97.6 +\label{chap:preface} 97.7 + 97.8 +El control distribuido de revisiones es un territorio relativamente 97.9 +nuevo, y ha crecido hasta ahora 97.10 +% TODO el original dice "due to", que sería "debido", pero creo que "gracias 97.11 +% a" queda mejor 97.12 +gracias a a la voluntad que tiene la gente de salir y explorar 97.13 +territorios desconocidos. 97.14 +% TODO revisar la frase anterior. me tomé muchas licencias para 97.15 +% traducirla 97.16 + 97.17 +Estoy escribiendo este libro acerca de control de revisiones 97.18 +distribuido porque creo que es un tema importante que merece una guía 97.19 +de campo. Escogí escribir acerca de Mercurial porque es la herramienta 97.20 +%TODO puse explorar en vez de aprender, you be the judge dear reviewer ;) 97.21 +más fácil para explorar el terreno, y sin embargo escala a las 97.22 +demandas de retadores ambientes reales donde muchas otras herramientas 97.23 +de control de revisiones fallan. 97.24 + 97.25 +\section{Este libro es un trabajo en progreso} 97.26 +Estoy liberando este libro mientras lo sigo escribiendo, con la 97.27 +esperanza de que pueda ser útil a otros. También espero que los 97.28 +lectores contribuirán como consideren adecuado. 97.29 + 97.30 +\section{Acerca de los ejemplos en este libro} 97.31 +Este libro toma un enfoque inusual hacia las muestras de código. Cada 97.32 +ejemplo está ``en directo''---cada uno es realmente el resultado de un 97.33 +% TODO shell script 97.34 +script de shell que ejecuta los comandos de Mercurial que usted ve. 97.35 +Cada vez que una copia del libro es construida desde su código fuente, 97.36 +% TODO scripts 97.37 +todos los scripts de ejemplo son ejecutados automáticamente, y sus 97.38 +resultados actuales son comparados contra los resultados esperados. 97.39 + 97.40 +La ventaja de este enfoque es que los ejemplos siempre son precisos; 97.41 +ellos describen \emph{exactamente} el comportamiento de la versión de 97.42 +Mercurial que es mencionada en la portada del libro. Si yo actualizo 97.43 +la versión de Mercurial que estoy documentando, y la salida de algún 97.44 +comando cambia, la construcción falla. 97.45 + 97.46 +Hay una pequeña desventaja de este enfoque, que las fechas y horas que 97.47 +usted verá en los ejemplos tienden a estar ``aplastadas'' juntas de una 97.48 +forma que no sería posible si los mismos comandos fueran escritos por 97.49 +un humano. Donde un humano puede emitir no más de un comando cada 97.50 +pocos segundos, con cualquier marca de tiempo resultante 97.51 +correspondientemente separada, mis scripts automatizados de ejemplos 97.52 +ejecutan muchos comandos en un segundo. 97.53 + 97.54 +% TODO commit 97.55 +Como un ejemplo de esto, varios commits consecutivos en un ejemplo 97.56 +pueden aparecer como habiendo ocurrido durante el mismo segundo. Usted 97.57 +puede ver esto en el ejemplo \hgext{bisect} en la 97.58 +sección~\ref{sec:undo:bisect}, por ejemplo. 97.59 + 97.60 +Así que cuando usted lea los ejemplos, no le dé mucha importancia a 97.61 +las fechas o horas que vea en las salidas de los comandos. Pero 97.62 +\emph{tenga} confianza en que el comportamiento que está viendo es 97.63 +consistente y reproducible. 97.64 + 97.65 +\section{Colofón---este libro es Libre} 97.66 +Este libro está licenciado bajo la Licencia de Publicación Abierta, y 97.67 +es producido en su totalidad usando herramientas de Software Libre. Es 97.68 +compuesto con \LaTeX{}; las ilustraciones son dibujadas y generadas 97.69 +con \href{http://www.inkscape.org/}{Inkscape}. 97.70 + 97.71 +El código fuente completo para este libro es publicado como un 97.72 +repositorio Mercurial, en \url{http://hg.serpentine.com/mercurial/book}. 97.73 + 97.74 +%%% Local Variables: 97.75 +%%% mode: latex 97.76 +%%% TeX-master: "00book" 97.77 +%%% End:
98.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 98.2 +++ b/es/revlog.svg Thu Jan 29 22:00:07 2009 -0800 98.3 @@ -0,0 +1,1164 @@ 98.4 +<?xml version="1.0" encoding="UTF-8" standalone="no"?> 98.5 +<!-- Created with Inkscape (http://www.inkscape.org/) --> 98.6 +<svg 98.7 + xmlns:dc="http://purl.org/dc/elements/1.1/" 98.8 + xmlns:cc="http://creativecommons.org/ns#" 98.9 + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 98.10 + xmlns:svg="http://www.w3.org/2000/svg" 98.11 + xmlns="http://www.w3.org/2000/svg" 98.12 + xmlns:xlink="http://www.w3.org/1999/xlink" 98.13 + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" 98.14 + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" 98.15 + width="744.09448819" 98.16 + height="1052.3622047" 98.17 + id="svg2" 98.18 + sodipodi:version="0.32" 98.19 + inkscape:version="0.46" 98.20 + sodipodi:docbase="/home/bos/hg/hgbook/en" 98.21 + sodipodi:docname="revlog.svg" 98.22 + inkscape:output_extension="org.inkscape.output.svg.inkscape"> 98.23 + <defs 98.24 + id="defs4"> 98.25 + <inkscape:perspective 98.26 + sodipodi:type="inkscape:persp3d" 98.27 + inkscape:vp_x="0 : 526.18109 : 1" 98.28 + inkscape:vp_y="0 : 1000 : 0" 98.29 + inkscape:vp_z="744.09448 : 526.18109 : 1" 98.30 + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" 98.31 + id="perspective2726" /> 98.32 + <marker 98.33 + inkscape:stockid="Arrow1Mend" 98.34 + orient="auto" 98.35 + refY="0.0" 98.36 + refX="0.0" 98.37 + id="Arrow1Mend" 98.38 + style="overflow:visible;"> 98.39 + <path 98.40 + id="path4852" 98.41 + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " 98.42 + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;" 98.43 + transform="scale(0.4) rotate(180) translate(10,0)" /> 98.44 + </marker> 98.45 + <linearGradient 98.46 + id="linearGradient3092"> 98.47 + <stop 98.48 + style="stop-color:#44436f;stop-opacity:1;" 98.49 + offset="0" 98.50 + id="stop3094" /> 98.51 + <stop 98.52 + style="stop-color:#abade5;stop-opacity:1;" 98.53 + offset="1" 98.54 + id="stop3096" /> 98.55 + </linearGradient> 98.56 + <linearGradient 98.57 + inkscape:collect="always" 98.58 + xlink:href="#linearGradient3092" 98.59 + id="linearGradient3118" 98.60 + gradientUnits="userSpaceOnUse" 98.61 + x1="176.16635" 98.62 + y1="405.21934" 98.63 + x2="417.11935" 98.64 + y2="405.21934" /> 98.65 + <linearGradient 98.66 + inkscape:collect="always" 98.67 + xlink:href="#linearGradient3092" 98.68 + id="linearGradient3120" 98.69 + gradientUnits="userSpaceOnUse" 98.70 + x1="176.16635" 98.71 + y1="405.21934" 98.72 + x2="417.11935" 98.73 + y2="405.21934" /> 98.74 + <linearGradient 98.75 + inkscape:collect="always" 98.76 + xlink:href="#linearGradient3092" 98.77 + id="linearGradient3129" 98.78 + gradientUnits="userSpaceOnUse" 98.79 + x1="176.16635" 98.80 + y1="405.21934" 98.81 + x2="417.11935" 98.82 + y2="405.21934" 98.83 + gradientTransform="translate(-0.928574,-1.428574)" /> 98.84 + <linearGradient 98.85 + inkscape:collect="always" 98.86 + xlink:href="#linearGradient3092" 98.87 + id="linearGradient3133" 98.88 + gradientUnits="userSpaceOnUse" 98.89 + x1="176.16635" 98.90 + y1="405.21934" 98.91 + x2="417.11935" 98.92 + y2="405.21934" 98.93 + gradientTransform="translate(-0.928574,-1.428574)" /> 98.94 + <linearGradient 98.95 + inkscape:collect="always" 98.96 + xlink:href="#linearGradient3092" 98.97 + id="linearGradient3708" 98.98 + gradientUnits="userSpaceOnUse" 98.99 + gradientTransform="matrix(0.423343,0,0,0.423343,138.874,-67.01732)" 98.100 + x1="175.23776" 98.101 + y1="509.98154" 98.102 + x2="416.29077" 98.103 + y2="297.49997" /> 98.104 + <linearGradient 98.105 + inkscape:collect="always" 98.106 + xlink:href="#linearGradient3092" 98.107 + id="linearGradient5164" 98.108 + gradientUnits="userSpaceOnUse" 98.109 + gradientTransform="matrix(0.423343,0,0,0.423343,198.249,247.4358)" 98.110 + x1="175.23776" 98.111 + y1="509.98154" 98.112 + x2="416.29077" 98.113 + y2="297.49997" /> 98.114 + <linearGradient 98.115 + inkscape:collect="always" 98.116 + xlink:href="#linearGradient3092" 98.117 + id="linearGradient5584" 98.118 + gradientUnits="userSpaceOnUse" 98.119 + gradientTransform="matrix(0.423343,0,0,0.423343,143.9081,371.2915)" 98.120 + x1="175.23776" 98.121 + y1="509.98154" 98.122 + x2="416.29077" 98.123 + y2="297.49997" /> 98.124 + <linearGradient 98.125 + inkscape:collect="always" 98.126 + xlink:href="#linearGradient3092" 98.127 + id="linearGradient5784" 98.128 + gradientUnits="userSpaceOnUse" 98.129 + gradientTransform="matrix(0.423343,0,0,0.423343,76.37397,152.137)" 98.130 + x1="175.23776" 98.131 + y1="509.98154" 98.132 + x2="416.29077" 98.133 + y2="297.49997" /> 98.134 + <linearGradient 98.135 + inkscape:collect="always" 98.136 + xlink:href="#linearGradient3092" 98.137 + id="linearGradient5786" 98.138 + gradientUnits="userSpaceOnUse" 98.139 + gradientTransform="matrix(0.423343,0,0,0.423343,198.249,152.137)" 98.140 + x1="175.23776" 98.141 + y1="509.98154" 98.142 + x2="416.29077" 98.143 + y2="297.49997" /> 98.144 + <linearGradient 98.145 + inkscape:collect="always" 98.146 + xlink:href="#linearGradient3092" 98.147 + id="linearGradient5895" 98.148 + gradientUnits="userSpaceOnUse" 98.149 + gradientTransform="matrix(0.423343,0,0,0.423343,198.0215,261.7142)" 98.150 + x1="175.23776" 98.151 + y1="509.98154" 98.152 + x2="416.29077" 98.153 + y2="297.49997" /> 98.154 + <linearGradient 98.155 + inkscape:collect="always" 98.156 + xlink:href="#linearGradient3092" 98.157 + id="linearGradient5958" 98.158 + gradientUnits="userSpaceOnUse" 98.159 + gradientTransform="matrix(0.423343,0,0,0.423343,137.1978,42.55987)" 98.160 + x1="175.23776" 98.161 + y1="509.98154" 98.162 + x2="416.29077" 98.163 + y2="297.49997" /> 98.164 + </defs> 98.165 + <sodipodi:namedview 98.166 + id="base" 98.167 + pagecolor="#ffffff" 98.168 + bordercolor="#666666" 98.169 + borderopacity="1.0" 98.170 + gridtolerance="10000" 98.171 + guidetolerance="10" 98.172 + objecttolerance="10" 98.173 + inkscape:pageopacity="0.0" 98.174 + inkscape:pageshadow="2" 98.175 + inkscape:zoom="1.8101934" 98.176 + inkscape:cx="199.78816" 98.177 + inkscape:cy="863.27363" 98.178 + inkscape:document-units="px" 98.179 + inkscape:current-layer="layer1" 98.180 + inkscape:window-width="906" 98.181 + inkscape:window-height="659" 98.182 + inkscape:window-x="29" 98.183 + inkscape:window-y="79" 98.184 + inkscape:connector-spacing="11" 98.185 + showgrid="false" /> 98.186 + <metadata 98.187 + id="metadata7"> 98.188 + <rdf:RDF> 98.189 + <cc:Work 98.190 + rdf:about=""> 98.191 + <dc:format>image/svg+xml</dc:format> 98.192 + <dc:type 98.193 + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> 98.194 + </cc:Work> 98.195 + </rdf:RDF> 98.196 + </metadata> 98.197 + <g 98.198 + inkscape:label="Layer 1" 98.199 + inkscape:groupmode="layer" 98.200 + id="layer1"> 98.201 + <rect 98.202 + y="168.74846" 98.203 + x="211.58516" 98.204 + height="89.506805" 98.205 + width="101.60232" 98.206 + id="rect3068" 98.207 + style="fill:url(#linearGradient5958);fill-opacity:1;stroke:black;stroke-width:0.48811448;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> 98.208 + <g 98.209 + id="g3215" 98.210 + transform="matrix(0.423343,0,0,0.423343,137.1977,42.55985)"> 98.211 + <rect 98.212 + y="447.71451" 98.213 + x="299.67859" 98.214 + height="48.571426" 98.215 + width="103.14286" 98.216 + id="rect2899" 98.217 + style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> 98.218 + <text 98.219 + id="text2903" 98.220 + y="464.8139" 98.221 + x="308.89639" 98.222 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.223 + xml:space="preserve"><tspan 98.224 + y="464.8139" 98.225 + x="308.89639" 98.226 + sodipodi:role="line" 98.227 + id="tspan2905">Segundo padre</tspan></text> 98.228 + <text 98.229 + id="text2907" 98.230 + y="485.50256" 98.231 + x="308.20175" 98.232 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.233 + xml:space="preserve"><tspan 98.234 + style="font-family:Courier" 98.235 + y="485.50256" 98.236 + x="308.20175" 98.237 + id="tspan2909" 98.238 + sodipodi:role="line">32bf9a5f22c0</tspan></text> 98.239 + </g> 98.240 + <g 98.241 + id="g3250" 98.242 + transform="matrix(0.423343,0,0,0.423343,137.1977,42.55986)"> 98.243 + <rect 98.244 + y="311.28598" 98.245 + x="188.6071" 98.246 + height="48.571426" 98.247 + width="103.14286" 98.248 + id="rect2936" 98.249 + style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> 98.250 + <text 98.251 + id="text2940" 98.252 + y="328.38538" 98.253 + x="197.82495" 98.254 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.255 + xml:space="preserve"><tspan 98.256 + y="328.38538" 98.257 + x="197.82495" 98.258 + sodipodi:role="line" 98.259 + id="tspan2942">Hash de revisión</tspan></text> 98.260 + <text 98.261 + id="text2944" 98.262 + y="349.07404" 98.263 + x="197.13031" 98.264 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.265 + xml:space="preserve"><tspan 98.266 + style="font-family:Courier" 98.267 + y="349.07404" 98.268 + x="197.13031" 98.269 + id="tspan2946" 98.270 + sodipodi:role="line">34b8b7a15ea1</tspan></text> 98.271 + </g> 98.272 + <g 98.273 + id="g3243" 98.274 + transform="matrix(0.423343,0,0,0.423343,137.6664,43.91853)"> 98.275 + <rect 98.276 + y="363.07654" 98.277 + x="187.5" 98.278 + height="75" 98.279 + width="213.85715" 98.280 + id="rect2950" 98.281 + style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> 98.282 + <text 98.283 + id="text2958" 98.284 + y="400.86459" 98.285 + x="196.02321" 98.286 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.287 + xml:space="preserve"><tspan 98.288 + style="fill:black;fill-opacity:1;font-family:Courier" 98.289 + y="400.86459" 98.290 + x="196.02321" 98.291 + id="tspan2960" 98.292 + sodipodi:role="line">...</tspan></text> 98.293 + <text 98.294 + id="text2954" 98.295 + y="380.17593" 98.296 + x="196.71785" 98.297 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.298 + xml:space="preserve"><tspan 98.299 + y="380.17593" 98.300 + x="196.71785" 98.301 + sodipodi:role="line" 98.302 + id="tspan2956" 98.303 + style="fill:#000000;fill-opacity:1">Datos de Revisión (delta o snapshot)</tspan></text> 98.304 + </g> 98.305 + <g 98.306 + id="g5529" 98.307 + transform="translate(-6.710312,-8.165836e-6)"> 98.308 + <rect 98.309 + style="fill:url(#linearGradient5584);fill-opacity:1;stroke:black;stroke-width:0.48811448;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 98.310 + id="rect3509" 98.311 + width="101.60232" 98.312 + height="89.506805" 98.313 + x="218.29547" 98.314 + y="497.4801" /> 98.315 + <g 98.316 + transform="matrix(0.423343,0,0,0.423343,143.908,371.2915)" 98.317 + id="g3513"> 98.318 + <g 98.319 + id="g3515"> 98.320 + <rect 98.321 + y="447.72418" 98.322 + x="188.6071" 98.323 + height="48.571426" 98.324 + width="103.14286" 98.325 + id="rect3517" 98.326 + style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> 98.327 + <text 98.328 + id="text3519" 98.329 + y="464.82358" 98.330 + x="197.82495" 98.331 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.332 + xml:space="preserve"><tspan 98.333 + y="464.82358" 98.334 + x="197.82495" 98.335 + sodipodi:role="line" 98.336 + id="tspan3521">Primer padre</tspan></text> 98.337 + <text 98.338 + id="text3523" 98.339 + y="485.51224" 98.340 + x="197.13031" 98.341 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.342 + xml:space="preserve"><tspan 98.343 + style="font-family:Courier" 98.344 + y="485.51224" 98.345 + x="197.13031" 98.346 + id="tspan3525" 98.347 + sodipodi:role="line">000000000000</tspan></text> 98.348 + </g> 98.349 + <g 98.350 + id="g3527"> 98.351 + <rect 98.352 + y="447.71451" 98.353 + x="299.67859" 98.354 + height="48.571426" 98.355 + width="103.14286" 98.356 + id="rect3529" 98.357 + style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> 98.358 + <text 98.359 + id="text3531" 98.360 + y="464.8139" 98.361 + x="308.89639" 98.362 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.363 + xml:space="preserve"><tspan 98.364 + y="464.8139" 98.365 + x="308.89639" 98.366 + sodipodi:role="line" 98.367 + id="tspan3533">Segundo padre</tspan></text> 98.368 + <text 98.369 + id="text3535" 98.370 + y="485.50256" 98.371 + x="308.20175" 98.372 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.373 + xml:space="preserve"><tspan 98.374 + style="font-family:Courier" 98.375 + y="485.50256" 98.376 + x="308.20175" 98.377 + id="tspan3537" 98.378 + sodipodi:role="line">000000000000</tspan></text> 98.379 + </g> 98.380 + </g> 98.381 + <g 98.382 + transform="matrix(0.423343,0,0,0.423343,143.908,371.2915)" 98.383 + id="g3539"> 98.384 + <rect 98.385 + style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 98.386 + id="rect3541" 98.387 + width="103.14286" 98.388 + height="48.571426" 98.389 + x="188.6071" 98.390 + y="311.28598" /> 98.391 + <text 98.392 + xml:space="preserve" 98.393 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.394 + x="197.82495" 98.395 + y="328.38538" 98.396 + id="text3543"><tspan 98.397 + id="tspan3545" 98.398 + sodipodi:role="line" 98.399 + x="197.82495" 98.400 + y="328.38538">Hash de revisión</tspan></text> 98.401 + <text 98.402 + xml:space="preserve" 98.403 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.404 + x="197.13031" 98.405 + y="349.07404" 98.406 + id="text3547"><tspan 98.407 + sodipodi:role="line" 98.408 + id="tspan3549" 98.409 + x="197.13031" 98.410 + y="349.07404" 98.411 + style="font-family:Courier">ff9dc8bc2a8b</tspan></text> 98.412 + </g> 98.413 + <g 98.414 + transform="matrix(0.423343,0,0,0.423343,144.3767,372.6502)" 98.415 + id="g3551"> 98.416 + <rect 98.417 + style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 98.418 + id="rect3553" 98.419 + width="213.85715" 98.420 + height="75" 98.421 + x="187.5" 98.422 + y="363.07654" /> 98.423 + <text 98.424 + xml:space="preserve" 98.425 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.426 + x="196.02321" 98.427 + y="400.86459" 98.428 + id="text3555"><tspan 98.429 + sodipodi:role="line" 98.430 + id="tspan3557" 98.431 + x="196.02321" 98.432 + y="400.86459" 98.433 + style="fill:black;fill-opacity:1;font-family:Courier">...</tspan></text> 98.434 + <text 98.435 + xml:space="preserve" 98.436 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.437 + x="196.71785" 98.438 + y="380.17593" 98.439 + id="text3559"><tspan 98.440 + style="fill:#000000;fill-opacity:1" 98.441 + id="tspan3561" 98.442 + sodipodi:role="line" 98.443 + x="196.71785" 98.444 + y="380.17593">Datos de revisión (delta o snapshot)</tspan></text> 98.445 + </g> 98.446 + </g> 98.447 + <g 98.448 + id="g4868" 98.449 + transform="translate(-1.676208,-2.342463e-5)"> 98.450 + <rect 98.451 + style="fill:url(#linearGradient3708);fill-opacity:1;stroke:black;stroke-width:0.48811448;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 98.452 + id="rect3567" 98.453 + width="101.60232" 98.454 + height="89.506805" 98.455 + x="213.26137" 98.456 + y="59.171272" /> 98.457 + <g 98.458 + transform="matrix(0.423343,0,0,0.423343,138.8739,-67.01734)" 98.459 + id="g3573"> 98.460 + <rect 98.461 + style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 98.462 + id="rect3575" 98.463 + width="103.14286" 98.464 + height="48.571426" 98.465 + x="188.6071" 98.466 + y="447.72418" /> 98.467 + <text 98.468 + xml:space="preserve" 98.469 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.470 + x="197.82495" 98.471 + y="464.82358" 98.472 + id="text3577"><tspan 98.473 + id="tspan3579" 98.474 + sodipodi:role="line" 98.475 + x="197.82495" 98.476 + y="464.82358">Primer padre</tspan></text> 98.477 + <text 98.478 + xml:space="preserve" 98.479 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.480 + x="197.13031" 98.481 + y="485.51224" 98.482 + id="text3581"><tspan 98.483 + sodipodi:role="line" 98.484 + id="tspan3583" 98.485 + x="197.13031" 98.486 + y="485.51224" 98.487 + style="font-family:Courier">34b8b7a15ea1</tspan></text> 98.488 + </g> 98.489 + <g 98.490 + transform="matrix(0.423343,0,0,0.423343,138.8739,-67.01734)" 98.491 + id="g3585"> 98.492 + <rect 98.493 + style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 98.494 + id="rect3587" 98.495 + width="103.14286" 98.496 + height="48.571426" 98.497 + x="299.67859" 98.498 + y="447.71451" /> 98.499 + <text 98.500 + xml:space="preserve" 98.501 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.502 + x="308.89639" 98.503 + y="464.8139" 98.504 + id="text3589"><tspan 98.505 + id="tspan3591" 98.506 + sodipodi:role="line" 98.507 + x="308.89639" 98.508 + y="464.8139">Segundo padre</tspan></text> 98.509 + <text 98.510 + xml:space="preserve" 98.511 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.512 + x="308.20175" 98.513 + y="485.50256" 98.514 + id="text3593"><tspan 98.515 + sodipodi:role="line" 98.516 + id="tspan3595" 98.517 + x="308.20175" 98.518 + y="485.50256" 98.519 + style="font-family:Courier">000000000000</tspan></text> 98.520 + </g> 98.521 + <g 98.522 + transform="matrix(0.423343,0,0,0.423343,138.8739,-67.01733)" 98.523 + id="g3597"> 98.524 + <rect 98.525 + style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 98.526 + id="rect3599" 98.527 + width="103.14286" 98.528 + height="48.571426" 98.529 + x="188.6071" 98.530 + y="311.28598" /> 98.531 + <text 98.532 + xml:space="preserve" 98.533 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.534 + x="197.82495" 98.535 + y="328.38538" 98.536 + id="text3601"><tspan 98.537 + id="tspan3603" 98.538 + sodipodi:role="line" 98.539 + x="197.82495" 98.540 + y="328.38538">Hash de revisión</tspan></text> 98.541 + <text 98.542 + xml:space="preserve" 98.543 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.544 + x="197.13031" 98.545 + y="349.07404" 98.546 + id="text3605"><tspan 98.547 + sodipodi:role="line" 98.548 + id="tspan3607" 98.549 + x="197.13031" 98.550 + y="349.07404" 98.551 + style="font-family:Courier">1b67dc96f27a</tspan></text> 98.552 + </g> 98.553 + <g 98.554 + transform="matrix(0.423343,0,0,0.423343,139.3426,-65.65866)" 98.555 + id="g3609"> 98.556 + <rect 98.557 + style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 98.558 + id="rect3611" 98.559 + width="213.85715" 98.560 + height="75" 98.561 + x="187.5" 98.562 + y="363.07654" /> 98.563 + <text 98.564 + xml:space="preserve" 98.565 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.566 + x="196.02321" 98.567 + y="400.86459" 98.568 + id="text3613"><tspan 98.569 + sodipodi:role="line" 98.570 + id="tspan3615" 98.571 + x="196.02321" 98.572 + y="400.86459" 98.573 + style="fill:black;fill-opacity:1;font-family:Courier">...</tspan></text> 98.574 + <text 98.575 + xml:space="preserve" 98.576 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.577 + x="196.71785" 98.578 + y="380.17593" 98.579 + id="text3617"><tspan 98.580 + style="fill:#000000;fill-opacity:1" 98.581 + id="tspan3619" 98.582 + sodipodi:role="line" 98.583 + x="196.71785" 98.584 + y="380.17593">Datos de revisión (delta o snapshot)</tspan></text> 98.585 + </g> 98.586 + </g> 98.587 + <path 98.588 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:none;marker-end:url(#Arrow1Mend)" 98.589 + d="M 240.78255,143.08593 L 241.42595,171.75349" 98.590 + id="path3801" 98.591 + inkscape:connector-type="polyline" 98.592 + inkscape:connection-start="#g3573" 98.593 + inkscape:connection-end="#g3250" /> 98.594 + <g 98.595 + id="g5677"> 98.596 + <rect 98.597 + style="fill:url(#linearGradient5784);fill-opacity:1;stroke:black;stroke-width:0.48811448;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 98.598 + id="rect3393" 98.599 + width="101.60232" 98.600 + height="89.506805" 98.601 + x="150.76137" 98.602 + y="278.32565" /> 98.603 + <g 98.604 + transform="matrix(0.423343,0,0,0.423343,76.37397,152.137)" 98.605 + id="g3399"> 98.606 + <rect 98.607 + style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 98.608 + id="rect3401" 98.609 + width="103.14286" 98.610 + height="48.571426" 98.611 + x="188.6071" 98.612 + y="447.72418" /> 98.613 + <text 98.614 + xml:space="preserve" 98.615 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.616 + x="197.82495" 98.617 + y="464.82358" 98.618 + id="text3403"><tspan 98.619 + id="tspan3405" 98.620 + sodipodi:role="line" 98.621 + x="197.82495" 98.622 + y="464.82358">Primer padre</tspan></text> 98.623 + <text 98.624 + xml:space="preserve" 98.625 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.626 + x="197.13031" 98.627 + y="485.51224" 98.628 + id="text3407"><tspan 98.629 + sodipodi:role="line" 98.630 + id="tspan3409" 98.631 + x="197.13031" 98.632 + y="485.51224" 98.633 + style="font-family:Courier">ff9dc8bc2a8b</tspan></text> 98.634 + </g> 98.635 + <g 98.636 + transform="matrix(0.423343,0,0,0.423343,76.37397,152.137)" 98.637 + id="g3411"> 98.638 + <rect 98.639 + style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 98.640 + id="rect3413" 98.641 + width="103.14286" 98.642 + height="48.571426" 98.643 + x="299.67859" 98.644 + y="447.71451" /> 98.645 + <text 98.646 + xml:space="preserve" 98.647 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.648 + x="308.89639" 98.649 + y="464.8139" 98.650 + id="text3415"><tspan 98.651 + id="tspan3417" 98.652 + sodipodi:role="line" 98.653 + x="308.89639" 98.654 + y="464.8139">Segundo padre</tspan></text> 98.655 + <text 98.656 + xml:space="preserve" 98.657 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.658 + x="308.20175" 98.659 + y="485.50256" 98.660 + id="text3419"><tspan 98.661 + sodipodi:role="line" 98.662 + id="tspan3421" 98.663 + x="308.20175" 98.664 + y="485.50256" 98.665 + style="font-family:Courier">000000000000</tspan></text> 98.666 + </g> 98.667 + <g 98.668 + transform="matrix(0.423343,0,0,0.423343,76.37397,152.137)" 98.669 + id="g3423"> 98.670 + <rect 98.671 + style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 98.672 + id="rect3425" 98.673 + width="103.14286" 98.674 + height="48.571426" 98.675 + x="188.6071" 98.676 + y="311.28598" /> 98.677 + <text 98.678 + xml:space="preserve" 98.679 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.680 + x="197.82495" 98.681 + y="328.38538" 98.682 + id="text3427"><tspan 98.683 + id="tspan3429" 98.684 + sodipodi:role="line" 98.685 + x="197.82495" 98.686 + y="328.38538">Hash de revisión</tspan></text> 98.687 + <text 98.688 + xml:space="preserve" 98.689 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.690 + x="197.13031" 98.691 + y="349.07404" 98.692 + id="text3431"><tspan 98.693 + sodipodi:role="line" 98.694 + id="tspan3433" 98.695 + x="197.13031" 98.696 + y="349.07404" 98.697 + style="font-family:Courier">5b80c922ebdd</tspan></text> 98.698 + </g> 98.699 + <g 98.700 + transform="matrix(0.423343,0,0,0.423343,76.84265,153.4957)" 98.701 + id="g3435"> 98.702 + <rect 98.703 + style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 98.704 + id="rect3437" 98.705 + width="213.85715" 98.706 + height="75" 98.707 + x="187.5" 98.708 + y="363.07654" /> 98.709 + <text 98.710 + xml:space="preserve" 98.711 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.712 + x="196.02321" 98.713 + y="400.86459" 98.714 + id="text3439"><tspan 98.715 + sodipodi:role="line" 98.716 + id="tspan3441" 98.717 + x="196.02321" 98.718 + y="400.86459" 98.719 + style="fill:black;fill-opacity:1;font-family:Courier">...</tspan></text> 98.720 + <text 98.721 + xml:space="preserve" 98.722 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.723 + x="196.71785" 98.724 + y="380.17593" 98.725 + id="text3443"><tspan 98.726 + style="fill:#000000;fill-opacity:1" 98.727 + id="tspan3445" 98.728 + sodipodi:role="line" 98.729 + x="196.71785" 98.730 + y="380.17593">Datos de revisión (delta o snapshot)</tspan></text> 98.731 + </g> 98.732 + </g> 98.733 + <g 98.734 + id="g5646" 98.735 + transform="translate(-0.227432,0)"> 98.736 + <rect 98.737 + style="fill:url(#linearGradient5786);fill-opacity:1;stroke:black;stroke-width:0.48811448;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 98.738 + id="rect3451" 98.739 + width="101.60232" 98.740 + height="89.506805" 98.741 + x="272.63638" 98.742 + y="278.32565" /> 98.743 + <g 98.744 + transform="matrix(0.423343,0,0,0.423343,198.2489,152.137)" 98.745 + id="g3457"> 98.746 + <rect 98.747 + style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 98.748 + id="rect3459" 98.749 + width="103.14286" 98.750 + height="48.571426" 98.751 + x="188.6071" 98.752 + y="447.72418" /> 98.753 + <text 98.754 + xml:space="preserve" 98.755 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.756 + x="197.82495" 98.757 + y="464.82358" 98.758 + id="text3461"><tspan 98.759 + id="tspan3463" 98.760 + sodipodi:role="line" 98.761 + x="197.82495" 98.762 + y="464.82358">Primer padre</tspan></text> 98.763 + <text 98.764 + xml:space="preserve" 98.765 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.766 + x="197.13031" 98.767 + y="485.51224" 98.768 + id="text3465"><tspan 98.769 + sodipodi:role="line" 98.770 + id="tspan3467" 98.771 + x="197.13031" 98.772 + y="485.51224" 98.773 + style="font-family:Courier">ecacb6b4c9fd</tspan></text> 98.774 + </g> 98.775 + <g 98.776 + transform="matrix(0.423343,0,0,0.423343,198.2489,152.137)" 98.777 + id="g3469"> 98.778 + <rect 98.779 + style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 98.780 + id="rect3471" 98.781 + width="103.14286" 98.782 + height="48.571426" 98.783 + x="299.67859" 98.784 + y="447.71451" /> 98.785 + <text 98.786 + xml:space="preserve" 98.787 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.788 + x="308.89639" 98.789 + y="464.8139" 98.790 + id="text3473"><tspan 98.791 + id="tspan3475" 98.792 + sodipodi:role="line" 98.793 + x="308.89639" 98.794 + y="464.8139">Segundo padre</tspan></text> 98.795 + <text 98.796 + xml:space="preserve" 98.797 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.798 + x="308.20175" 98.799 + y="485.50256" 98.800 + id="text3477"><tspan 98.801 + sodipodi:role="line" 98.802 + id="tspan3479" 98.803 + x="308.20175" 98.804 + y="485.50256" 98.805 + style="font-family:Courier">000000000000</tspan></text> 98.806 + </g> 98.807 + <g 98.808 + transform="matrix(0.423343,0,0,0.423343,198.2489,152.137)" 98.809 + id="g3481"> 98.810 + <rect 98.811 + style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 98.812 + id="rect3483" 98.813 + width="103.14286" 98.814 + height="48.571426" 98.815 + x="188.6071" 98.816 + y="311.28598" /> 98.817 + <text 98.818 + xml:space="preserve" 98.819 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.820 + x="197.82495" 98.821 + y="328.38538" 98.822 + id="text3485"><tspan 98.823 + id="tspan3487" 98.824 + sodipodi:role="line" 98.825 + x="197.82495" 98.826 + y="328.38538">Hash de revisión</tspan></text> 98.827 + <text 98.828 + xml:space="preserve" 98.829 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.830 + x="197.13031" 98.831 + y="349.07404" 98.832 + id="text3489"><tspan 98.833 + sodipodi:role="line" 98.834 + id="tspan3491" 98.835 + x="197.13031" 98.836 + y="349.07404" 98.837 + style="font-family:Courier">32bf9a5f22c0</tspan></text> 98.838 + </g> 98.839 + <g 98.840 + transform="matrix(0.423343,0,0,0.423343,198.7176,153.4957)" 98.841 + id="g3493"> 98.842 + <rect 98.843 + style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 98.844 + id="rect3495" 98.845 + width="213.85715" 98.846 + height="75" 98.847 + x="187.5" 98.848 + y="363.07654" /> 98.849 + <text 98.850 + xml:space="preserve" 98.851 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.852 + x="196.02321" 98.853 + y="400.86459" 98.854 + id="text3497"><tspan 98.855 + sodipodi:role="line" 98.856 + id="tspan3499" 98.857 + x="196.02321" 98.858 + y="400.86459" 98.859 + style="fill:black;fill-opacity:1;font-family:Courier">...</tspan></text> 98.860 + <text 98.861 + xml:space="preserve" 98.862 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.863 + x="196.71785" 98.864 + y="380.17593" 98.865 + id="text3501"><tspan 98.866 + style="fill:#000000;fill-opacity:1" 98.867 + id="tspan3503" 98.868 + sodipodi:role="line" 98.869 + x="196.71785" 98.870 + y="380.17593">Datos de revisión (delta o snapshot)</tspan></text> 98.871 + </g> 98.872 + </g> 98.873 + <rect 98.874 + y="387.90286" 98.875 + x="272.40894" 98.876 + height="89.506805" 98.877 + width="101.60232" 98.878 + id="rect5081" 98.879 + style="fill:url(#linearGradient5895);fill-opacity:1;stroke:black;stroke-width:0.48811448;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> 98.880 + <g 98.881 + id="g5087" 98.882 + transform="matrix(0.423343,0,0,0.423343,198.0214,261.7142)"> 98.883 + <rect 98.884 + y="447.72418" 98.885 + x="188.6071" 98.886 + height="48.571426" 98.887 + width="103.14286" 98.888 + id="rect5089" 98.889 + style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> 98.890 + <text 98.891 + id="text5091" 98.892 + y="464.82358" 98.893 + x="197.82495" 98.894 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.895 + xml:space="preserve"><tspan 98.896 + y="464.82358" 98.897 + x="197.82495" 98.898 + sodipodi:role="line" 98.899 + id="tspan5093">Primer padre</tspan></text> 98.900 + <text 98.901 + id="text5095" 98.902 + y="485.51224" 98.903 + x="197.13031" 98.904 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.905 + xml:space="preserve"><tspan 98.906 + style="font-family:Courier" 98.907 + y="485.51224" 98.908 + x="197.13031" 98.909 + id="tspan5097" 98.910 + sodipodi:role="line">ff9dc8bc2a8b</tspan></text> 98.911 + </g> 98.912 + <g 98.913 + id="g5099" 98.914 + transform="matrix(0.423343,0,0,0.423343,198.0214,261.7142)"> 98.915 + <rect 98.916 + y="447.71451" 98.917 + x="299.67859" 98.918 + height="48.571426" 98.919 + width="103.14286" 98.920 + id="rect5101" 98.921 + style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> 98.922 + <text 98.923 + id="text5103" 98.924 + y="464.8139" 98.925 + x="308.89639" 98.926 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.927 + xml:space="preserve"><tspan 98.928 + y="464.8139" 98.929 + x="308.89639" 98.930 + sodipodi:role="line" 98.931 + id="tspan5105">Segundo padre</tspan></text> 98.932 + <text 98.933 + id="text5107" 98.934 + y="485.50256" 98.935 + x="308.20175" 98.936 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.937 + xml:space="preserve"><tspan 98.938 + style="font-family:Courier" 98.939 + y="485.50256" 98.940 + x="308.20175" 98.941 + id="tspan5109" 98.942 + sodipodi:role="line">000000000000</tspan></text> 98.943 + </g> 98.944 + <g 98.945 + id="g5111" 98.946 + transform="matrix(0.423343,0,0,0.423343,198.0214,261.7142)"> 98.947 + <rect 98.948 + y="311.28598" 98.949 + x="188.6071" 98.950 + height="48.571426" 98.951 + width="103.14286" 98.952 + id="rect5113" 98.953 + style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> 98.954 + <text 98.955 + id="text5115" 98.956 + y="328.38538" 98.957 + x="197.82495" 98.958 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.959 + xml:space="preserve"><tspan 98.960 + y="328.38538" 98.961 + x="197.82495" 98.962 + sodipodi:role="line" 98.963 + id="tspan5117">Hash de revisión</tspan></text> 98.964 + <text 98.965 + id="text5119" 98.966 + y="349.07404" 98.967 + x="197.13031" 98.968 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.969 + xml:space="preserve"><tspan 98.970 + style="font-family:Courier" 98.971 + y="349.07404" 98.972 + x="197.13031" 98.973 + id="tspan5121" 98.974 + sodipodi:role="line">ecacb6b4c9fd</tspan></text> 98.975 + </g> 98.976 + <g 98.977 + id="g5123" 98.978 + transform="matrix(0.423343,0,0,0.423343,198.4901,263.0729)"> 98.979 + <rect 98.980 + y="363.07654" 98.981 + x="187.5" 98.982 + height="75" 98.983 + width="213.85715" 98.984 + id="rect5125" 98.985 + style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> 98.986 + <text 98.987 + id="text5127" 98.988 + y="400.86459" 98.989 + x="196.02321" 98.990 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.991 + xml:space="preserve"><tspan 98.992 + style="fill:black;fill-opacity:1;font-family:Courier" 98.993 + y="400.86459" 98.994 + x="196.02321" 98.995 + id="tspan5129" 98.996 + sodipodi:role="line">...</tspan></text> 98.997 + <text 98.998 + id="text5131" 98.999 + y="380.17593" 98.1000 + x="196.71785" 98.1001 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.1002 + xml:space="preserve"><tspan 98.1003 + y="380.17593" 98.1004 + x="196.71785" 98.1005 + sodipodi:role="line" 98.1006 + id="tspan5133" 98.1007 + style="fill:#000000;fill-opacity:1">Datos de revisión (delta o snapshot)</tspan></text> 98.1008 + </g> 98.1009 + <path 98.1010 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline" 98.1011 + d="M 299.69935,362.24027 L 299.69931,393.49494" 98.1012 + id="path5203" 98.1013 + inkscape:connector-type="polyline" 98.1014 + inkscape:connection-start="#g3457" 98.1015 + inkscape:connection-end="#g5111" /> 98.1016 + <path 98.1017 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" 98.1018 + d="M 182.35357,362.22647 L 241.2842,503.07224" 98.1019 + id="path5271" 98.1020 + inkscape:connector-type="polyline" 98.1021 + inkscape:connection-start="#g3399" 98.1022 + inkscape:connection-end="#g3539" /> 98.1023 + <path 98.1024 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline" 98.1025 + d="M 287.63109,471.81747 L 250.9438,503.07223" 98.1026 + id="path5285" 98.1027 + inkscape:connector-type="polyline" 98.1028 + inkscape:connection-start="#g5087" 98.1029 + inkscape:connection-end="#g3539" /> 98.1030 + <path 98.1031 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)" 98.1032 + d="M 290.80419,250.07192 L 297.80065,283.90394" 98.1033 + id="path5077" 98.1034 + inkscape:connector-type="polyline" 98.1035 + inkscape:connection-start="#g3215" 98.1036 + inkscape:connection-end="#g3481" /> 98.1037 + <path 98.1038 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)" 98.1039 + d="M 229.63373,250.07601 L 190.07484,283.90394" 98.1040 + id="path5075" 98.1041 + inkscape:connector-type="polyline" 98.1042 + inkscape:connection-end="#g3423" /> 98.1043 + <text 98.1044 + xml:space="preserve" 98.1045 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.1046 + x="131.5625" 98.1047 + y="100.79968" 98.1048 + id="text5897"><tspan 98.1049 + sodipodi:role="line" 98.1050 + id="tspan5899" 98.1051 + x="131.5625" 98.1052 + y="100.79968" 98.1053 + style="text-align:end;text-anchor:end">Revisión principal</tspan><tspan 98.1054 + sodipodi:role="line" 98.1055 + x="131.5625" 98.1056 + y="115.79968" 98.1057 + id="tspan5901" 98.1058 + style="text-align:end;text-anchor:end">(sin hijos)</tspan></text> 98.1059 + <text 98.1060 + xml:space="preserve" 98.1061 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.1062 + x="131.5625" 98.1063 + y="207.04968" 98.1064 + id="text5903"><tspan 98.1065 + sodipodi:role="line" 98.1066 + id="tspan5905" 98.1067 + x="131.5625" 98.1068 + y="207.04968" 98.1069 + style="text-align:end;text-anchor:end">Revisión de fusión</tspan><tspan 98.1070 + sodipodi:role="line" 98.1071 + x="131.5625" 98.1072 + y="222.04968" 98.1073 + id="tspan5907" 98.1074 + style="text-align:end;text-anchor:end">(dos padres)</tspan></text> 98.1075 + <text 98.1076 + xml:space="preserve" 98.1077 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.1078 + x="131.92578" 98.1079 + y="451.58093" 98.1080 + id="text5909"><tspan 98.1081 + sodipodi:role="line" 98.1082 + id="tspan5911" 98.1083 + x="131.92578" 98.1084 + y="451.58093" 98.1085 + style="text-align:end;text-anchor:end">Ramas</tspan><tspan 98.1086 + sodipodi:role="line" 98.1087 + x="131.92578" 98.1088 + y="466.58093" 98.1089 + id="tspan5913" 98.1090 + style="text-align:end;text-anchor:end">(dos revisiones,</tspan><tspan 98.1091 + sodipodi:role="line" 98.1092 + x="131.92578" 98.1093 + y="481.58093" 98.1094 + id="tspan5915" 98.1095 + style="text-align:end;text-anchor:end">mismo padre)</tspan></text> 98.1096 + <path 98.1097 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 1;stroke-dashoffset:0;stroke-opacity:1;display:inline" 98.1098 + d="M 111.71875,433.61218 L 154.7268,368.52294" 98.1099 + id="path5917" 98.1100 + inkscape:connector-type="polyline" /> 98.1101 + <path 98.1102 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 1;stroke-dashoffset:0;stroke-opacity:1;display:inline" 98.1103 + d="M 134.375,464.86218 L 277.86691,440.37816" 98.1104 + id="path5919" 98.1105 + inkscape:connector-type="polyline" 98.1106 + inkscape:connection-end="#g5123" /> 98.1107 + <text 98.1108 + xml:space="preserve" 98.1109 + style="font-size:12px;font-style:normal;font-weight:normal;text-align:end;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.1110 + x="131.5625" 98.1111 + y="536.73718" 98.1112 + id="text5927"><tspan 98.1113 + sodipodi:role="line" 98.1114 + id="tspan5929" 98.1115 + x="131.5625" 98.1116 + y="536.73718">Primera revisión</tspan><tspan 98.1117 + sodipodi:role="line" 98.1118 + x="131.5625" 98.1119 + y="551.73718" 98.1120 + id="tspan5931">(ambos padres nulos)</tspan></text> 98.1121 + <rect 98.1122 + style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 98.1123 + id="rect2830" 98.1124 + width="43.664806" 98.1125 + height="20.562374" 98.1126 + x="217.0432" 98.1127 + y="232.10075" /> 98.1128 + <text 98.1129 + xml:space="preserve" 98.1130 + style="font-size:5.0801158px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.1131 + x="220.94551" 98.1132 + y="239.33966" 98.1133 + id="text2832"><tspan 98.1134 + id="tspan2836" 98.1135 + sodipodi:role="line" 98.1136 + x="220.94551" 98.1137 + y="239.33966">Primer padre</tspan></text> 98.1138 + <text 98.1139 + xml:space="preserve" 98.1140 + style="font-size:5.0801158px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 98.1141 + x="220.65144" 98.1142 + y="248.09805" 98.1143 + id="text2879"><tspan 98.1144 + sodipodi:role="line" 98.1145 + id="tspan2881" 98.1146 + x="220.65144" 98.1147 + y="248.09805" 98.1148 + style="font-family:Courier">5b80c922ebdd</tspan></text> 98.1149 + <path 98.1150 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 1;stroke-dashoffset:0;stroke-opacity:1;display:inline" 98.1151 + d="M 139.84375,107.83093 L 210.15625,107.83093" 98.1152 + id="path5965" 98.1153 + inkscape:connector-type="polyline" /> 98.1154 + <path 98.1155 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 1;stroke-dashoffset:0;stroke-opacity:1;display:inline" 98.1156 + d="M 137.5,213.29968 L 210.49036,214.09055" 98.1157 + id="path5967" 98.1158 + inkscape:connector-type="polyline" /> 98.1159 + <path 98.1160 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 1;stroke-dashoffset:0;stroke-opacity:1;display:inline" 98.1161 + d="M 136.34375,544.54968 L 206.65625,544.54968" 98.1162 + id="path5969" 98.1163 + inkscape:connector-type="polyline" 98.1164 + inkscape:transform-center-y="-171.09375" 98.1165 + inkscape:transform-center-x="53.90625" /> 98.1166 + </g> 98.1167 +</svg>
99.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 99.2 +++ b/es/snapshot.svg Thu Jan 29 22:00:07 2009 -0800 99.3 @@ -0,0 +1,212 @@ 99.4 +<?xml version="1.0" encoding="UTF-8" standalone="no"?> 99.5 +<!-- Created with Inkscape (http://www.inkscape.org/) --> 99.6 +<svg 99.7 + xmlns:dc="http://purl.org/dc/elements/1.1/" 99.8 + xmlns:cc="http://creativecommons.org/ns#" 99.9 + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 99.10 + xmlns:svg="http://www.w3.org/2000/svg" 99.11 + xmlns="http://www.w3.org/2000/svg" 99.12 + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" 99.13 + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" 99.14 + width="744.09448819" 99.15 + height="1052.3622047" 99.16 + id="svg2807" 99.17 + sodipodi:version="0.32" 99.18 + inkscape:version="0.46" 99.19 + sodipodi:docbase="/home/bos/hg/hgbook/en" 99.20 + sodipodi:docname="snapshot.svg" 99.21 + inkscape:output_extension="org.inkscape.output.svg.inkscape"> 99.22 + <defs 99.23 + id="defs2809"> 99.24 + <inkscape:perspective 99.25 + sodipodi:type="inkscape:persp3d" 99.26 + inkscape:vp_x="0 : 526.18109 : 1" 99.27 + inkscape:vp_y="0 : 1000 : 0" 99.28 + inkscape:vp_z="744.09448 : 526.18109 : 1" 99.29 + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" 99.30 + id="perspective2759" /> 99.31 + </defs> 99.32 + <sodipodi:namedview 99.33 + id="base" 99.34 + pagecolor="#ffffff" 99.35 + bordercolor="#666666" 99.36 + borderopacity="1.0" 99.37 + gridtolerance="10000" 99.38 + guidetolerance="10" 99.39 + objecttolerance="10" 99.40 + inkscape:pageopacity="0.0" 99.41 + inkscape:pageshadow="2" 99.42 + inkscape:zoom="1.4" 99.43 + inkscape:cx="252.04111" 99.44 + inkscape:cy="605.75448" 99.45 + inkscape:document-units="px" 99.46 + inkscape:current-layer="layer1" 99.47 + inkscape:window-width="906" 99.48 + inkscape:window-height="721" 99.49 + inkscape:window-x="141" 99.50 + inkscape:window-y="57" 99.51 + showgrid="false" /> 99.52 + <metadata 99.53 + id="metadata2812"> 99.54 + <rdf:RDF> 99.55 + <cc:Work 99.56 + rdf:about=""> 99.57 + <dc:format>image/svg+xml</dc:format> 99.58 + <dc:type 99.59 + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> 99.60 + </cc:Work> 99.61 + </rdf:RDF> 99.62 + </metadata> 99.63 + <g 99.64 + inkscape:label="Layer 1" 99.65 + inkscape:groupmode="layer" 99.66 + id="layer1"> 99.67 + <rect 99.68 + style="opacity:1;fill:#d3ceff;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.88795626;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 99.69 + id="rect2817" 99.70 + width="118.18347" 99.71 + height="245.32632" 99.72 + x="243.05112" 99.73 + y="315.4133" 99.74 + inkscape:transform-center-x="136.84403" 99.75 + inkscape:transform-center-y="-66.529183" /> 99.76 + <rect 99.77 + y="315.04153" 99.78 + x="46.965065" 99.79 + height="97.803009" 99.80 + width="108.92702" 99.81 + id="rect2815" 99.82 + style="fill:#ffced6;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.14441991;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> 99.83 + <g 99.84 + id="g3814"> 99.85 + <rect 99.86 + y="348.94302" 99.87 + x="59.285713" 99.88 + height="30" 99.89 + width="84.285713" 99.90 + id="rect2819" 99.91 + style="fill:#ff6e86;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 99.92 + ry="0" /> 99.93 + <text 99.94 + id="text2821" 99.95 + y="368.02701" 99.96 + x="72.717636" 99.97 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 99.98 + xml:space="preserve"><tspan 99.99 + y="368.02701" 99.100 + x="72.717636" 99.101 + id="tspan2823" 99.102 + sodipodi:role="line">Índice, rev 7</tspan></text> 99.103 + </g> 99.104 + <text 99.105 + id="text3722" 99.106 + y="303.43359" 99.107 + x="22.61635" 99.108 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 99.109 + xml:space="preserve"><tspan 99.110 + y="303.43359" 99.111 + x="22.61635" 99.112 + id="tspan3724" 99.113 + sodipodi:role="line">Índice de bitácora de revisiones (archivo .i)</tspan></text> 99.114 + <text 99.115 + id="text3726" 99.116 + y="301.29074" 99.117 + x="241.90207" 99.118 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 99.119 + xml:space="preserve"><tspan 99.120 + y="301.29074" 99.121 + x="241.90207" 99.122 + id="tspan3728" 99.123 + sodipodi:role="line">Datos de Bitacora de revisiones (archivo .d)</tspan></text> 99.124 + <path 99.125 + style="fill:#c695ff;fill-opacity:0.60109288;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" 99.126 + d="M 143.57143,348.07647 L 255,368.07646 L 255.71429,544.50504 L 142.85714,379.50504 L 143.57143,348.07647 z " 99.127 + id="path3839" 99.128 + sodipodi:nodetypes="ccccc" /> 99.129 + <rect 99.130 + style="fill:#4733ff;fill-opacity:1;stroke:#a7a7a7;stroke-width:2.35124183;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 99.131 + id="rect3752" 99.132 + width="92.720184" 99.133 + height="67.005905" 99.134 + x="255.42564" 99.135 + y="368.64264" /> 99.136 + <text 99.137 + xml:space="preserve" 99.138 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 99.139 + x="264.45859" 99.140 + y="387.30099" 99.141 + id="text3754"><tspan 99.142 + sodipodi:role="line" 99.143 + id="tspan3756" 99.144 + x="264.45859" 99.145 + y="387.30099">Snapshot, rev 4</tspan></text> 99.146 + <rect 99.147 + style="fill:#7c6eff;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.57776296;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 99.148 + id="rect3761" 99.149 + width="93.49366" 99.150 + height="29.922237" 99.151 + x="255.03891" 99.152 + y="442.04395" /> 99.153 + <text 99.154 + xml:space="preserve" 99.155 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 99.156 + x="263.2662" 99.157 + y="460.17206" 99.158 + id="text3763"><tspan 99.159 + sodipodi:role="line" 99.160 + id="tspan3765" 99.161 + x="263.2662" 99.162 + y="460.17206">Delta, rev 4 a 5</tspan></text> 99.163 + <rect 99.164 + style="fill:#7c6eff;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.57776296;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 99.165 + id="rect3774" 99.166 + width="93.49366" 99.167 + height="29.922237" 99.168 + x="255.03891" 99.169 + y="477.97485" /> 99.170 + <text 99.171 + xml:space="preserve" 99.172 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 99.173 + x="263.2662" 99.174 + y="496.10297" 99.175 + id="text3776"><tspan 99.176 + sodipodi:role="line" 99.177 + id="tspan3778" 99.178 + x="263.2662" 99.179 + y="496.10297">Delta, rev 5 a 6</tspan></text> 99.180 + <rect 99.181 + style="fill:#7c6eff;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.57776296;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 99.182 + id="rect3782" 99.183 + width="93.49366" 99.184 + height="29.922237" 99.185 + x="255.03891" 99.186 + y="513.90576" /> 99.187 + <text 99.188 + xml:space="preserve" 99.189 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 99.190 + x="263.2662" 99.191 + y="532.03387" 99.192 + id="text3784"><tspan 99.193 + sodipodi:role="line" 99.194 + id="tspan3786" 99.195 + x="263.2662" 99.196 + y="532.03387">Delta, rev 6 a 7</tspan></text> 99.197 + <rect 99.198 + style="fill:#7c6eff;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.57776296;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 99.199 + id="rect3889" 99.200 + width="93.49366" 99.201 + height="29.922237" 99.202 + x="255.03891" 99.203 + y="332.32489" /> 99.204 + <text 99.205 + xml:space="preserve" 99.206 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 99.207 + x="263.2662" 99.208 + y="350.453" 99.209 + id="text3891"><tspan 99.210 + sodipodi:role="line" 99.211 + id="tspan3893" 99.212 + x="263.2662" 99.213 + y="350.453">Delta, rev 2 a 3</tspan></text> 99.214 + </g> 99.215 +</svg>
100.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 100.2 +++ b/es/srcinstall.tex Thu Jan 29 22:00:07 2009 -0800 100.3 @@ -0,0 +1,55 @@ 100.4 +\chapter{Instalar Mercurial desde las fuentes} 100.5 +\label{chap:srcinstall} 100.6 + 100.7 +\section{En un sistema tipo Unix} 100.8 +\label{sec:srcinstall:unixlike} 100.9 + 100.10 +Si usa un sistema tipo Unix que tiene una versión suficientemente 100.11 +reciente de Python (2.3~o superior) disponible, es fácil instalar 100.12 +Mercurial desde las fuentes. 100.13 +\begin{enumerate} 100.14 +\item Descargue un paquete fuente reciente de 100.15 + \url{http://www.selenic.com/mercurial/download}. 100.16 +\item Descomprímalo: 100.17 + \begin{codesample4} 100.18 + gzip -dc mercurial-\emph{version}.tar.gz | tar xf - 100.19 + \end{codesample4} 100.20 +\item Vaya al directorio fuente y ejecute el guión de instalación. 100.21 + Esto armará Mercurial y lo instalará en su directorio casa: 100.22 + \begin{codesample4} 100.23 + cd mercurial-\emph{version} 100.24 + python setup.py install --force --home=\$HOME 100.25 + \end{codesample4} 100.26 +\end{enumerate} 100.27 +Cuando termine la instalación, Mercurial estará en el subdirectorio 100.28 +\texttt{bin} de su directorio casa. No olvide asegurarse de que este 100.29 +directorio esté presente en el camino de búsqueda de su intérprete de 100.30 +órdenes. 100.31 + 100.32 +Probablemente necesitará establecer la variable de ambiente 100.33 +\envar{PYTHONPATH} de tal forma que los ejecutables de Mercurial 100.34 +puedan encontrar el resto de los paquetes de Mercurial. Por ejemplo, 100.35 +en mi portátil, la establecía a \texttt{/home/bos/lib/python}. La 100.36 +ruta exacta que usted use dependerá de como ha sido construído Python 100.37 +en su sistema, pero debería ser fácil deducirla. Si no está seguro, 100.38 +mire lo que haya mostrado el script en el paso anterior, y vea dónde 100.39 +se instalaron los contenidos del directorio \texttt{mercurial} se 100.40 +instalaron. 100.41 + 100.42 +\section{En Windows} 100.43 + 100.44 +Armar e instalar Mercurial en Windows requiere una variedad de 100.45 +herramientas, cierta suficiencia técnica y paciencia considerable. 100.46 +Personalmente, \emph{no le recomiendo} hacerlo si es un ``usuario 100.47 +casual''. A menos que intente hacer hacks a Mercurial, le recomiendo 100.48 +que mejor use un paquete binario. 100.49 + 100.50 +Si está decidido a construir Mercurial desde las fuentes en Windows, 100.51 +siga el ``camino difícil'' indicado en el wiki de Mercurial en 100.52 +\url{http://www.selenic.com/mercurial/wiki/index.cgi/WindowsInstall}, 100.53 +y espere que el proceso sea realmente un trabajo duro. 100.54 + 100.55 +%%% Local Variables: 100.56 +%%% mode: latex 100.57 +%%% TeX-master: "00book" 100.58 +%%% End:
101.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 101.2 +++ b/es/template.tex Thu Jan 29 22:00:07 2009 -0800 101.3 @@ -0,0 +1,497 @@ 101.4 +\chapter{Personalizar los mensajes de Mercurial} 101.5 +\label{chap:template} 101.6 + 101.7 +Mercurial provee un poderoso mecanismo que permite controlar como 101.8 +despliega la información. El mecanismo se basa en plantillas. Puede 101.9 +usar plantillas para generar salida específica para una orden 101.10 +particular o para especificar la visualización completa de la interfaz 101.11 +web embebida. 101.12 + 101.13 +\section{Usar estilos que vienen con Mercurial} 101.14 +\label{sec:style} 101.15 + 101.16 +Hay ciertos estilos listos que vienen con Mercurial. Un estilo es 101.17 +simplemente una plantilla predeterminada que alguien escribió e 101.18 +instaló en un sitio en el cual Mercurial puede encontrarla. 101.19 + 101.20 +Antes de dar un vistazo a los estilos que trae Mercurial, revisemos su 101.21 +salida usual. 101.22 + 101.23 +\interaction{template.simple.normal} 101.24 + 101.25 +Es en cierta medida informativa, pero ocupa mucho espacio---cinco 101.26 +líneas de salida por cada conjunto de cambios. El estilo 101.27 +\texttt{compact} lo reduce a tres líneas, presentadas de forma 101.28 +suscinta. 101.29 + 101.30 +\interaction{template.simple.compact} 101.31 + 101.32 +El estilo de la \texttt{bitácora de cambios} vislumbra el poder 101.33 +expresivo del sistema de plantillas de Mercurial. Este estilo busca 101.34 +seguir los estándares de bitácora de cambios del proyecto 101.35 +GNU\cite{web:changelog}. 101.36 + 101.37 +\interaction{template.simple.changelog} 101.38 + 101.39 +No es una sorpresa que el estilo predeterminado de Mercurial se llame 101.40 +\texttt{default}\ndt{predeterminado}. 101.41 + 101.42 +\subsection{Especificar un estilo predeterminado} 101.43 + 101.44 +Puede modificar el estilo de presentación que Mercurial usará para 101.45 +toda orden vía el fichero \hgrc\, indicando el estilo que prefiere 101.46 +usar. 101.47 + 101.48 +\begin{codesample2} 101.49 + [ui] 101.50 + style = compact 101.51 +\end{codesample2} 101.52 + 101.53 +Si escribe un estilo, puede usarlo bien sea proveyendo la ruta a su 101.54 +fichero de estilo o copiando su fichero de estilo a un lugar en el 101.55 +cual Mercurial pueda encontrarlo (típicamente el subdirectorio 101.56 +\texttt{templates} de su directorio de instalación de Mercurial). 101.57 + 101.58 +\section{Órdenes que soportan estilos y plantillas} 101.59 + 101.60 +Todas las órdenes de Mercurial``relacionadas con \texttt{log}'' le 101.61 +permiten usar estilos y plantillas: \hgcmd{incoming}, \hgcmd{log}, 101.62 +\hgcmd{outgoing} y \hgcmd{tip}. 101.63 + 101.64 +Al momento de la escritura del manual estas son las únicas órdenes que 101.65 +soportan estilos y plantillas. Dado que son las órdenes más 101.66 +importantes que necesitan personalización, no ha habido muchas 101.67 +solicitudes desde la comunidad de usuarios de Mercurial para añadir 101.68 +soporte de plantillas y estilos a otras órdenes. 101.69 + 101.70 +\section{Cuestiones básicas de plantillas} 101.71 + 101.72 +Una plantilla de Mercurial es sencillamente una pieza de texto. 101.73 +Cierta porción nunca cambia, otras partes se \emph{expanden}, o 101.74 +reemplazan con texto nuevo cuando es necesario. 101.75 + 101.76 +Antes de continuar, veamos de nuevo un ejemplo sencillo de la salida 101.77 +usual de Mercurial: 101.78 + 101.79 +\interaction{template.simple.normal} 101.80 + 101.81 +Ahora, ejecutemos la misma orden, pero usemos una plantilla para 101.82 +modificar su salida: 101.83 + 101.84 +\interaction{template.simple.simplest} 101.85 + 101.86 +El ejemplo anterior ilustra la plantilla más sencilla posible; es 101.87 +solamente una porción estática de código que se imprime una vez por 101.88 +cada conjunto de cambios. La opción \hgopt{log}{--template} de la 101.89 +orden \hgcmd{log} indica a Mercurial usar el texto dado como la 101.90 +plantilla cuando se imprime cada conjunto de cambios. 101.91 + 101.92 +Observe que la cadena de plantilla anterior termina con el texto 101.93 +``\Verb+\n+''. Es una \emph{secuencia de control}, que le indica a 101.94 +Mercurial imprimira una nueva línea al final de cada objeto de la 101.95 +plantilla. Si omite esta nueva línea, Mercurial colocará cada pieza 101.96 +de salida seguida. Si desea más detalles acerca de secuencias de 101.97 +control, vea la sección~\ref{sec:template:escape}. 101.98 + 101.99 +Una plantilla que imprime una cadena fija de texto siempre no es muy 101.100 +útil; intentemos algo un poco más complejo. 101.101 + 101.102 +\interaction{template.simple.simplesub} 101.103 + 101.104 +Como puede ver, la cadena ``\Verb+{desc}+'' en la plantilla ha sido 101.105 +reemplazada en la salida con la descricipción de cada conjunto de 101.106 +cambios. Cada vez que Mercurial encuentra texto encerrado entre 101.107 +corchetes (``\texttt{\{}'' y ``\texttt{\}}''), intentará reemplazar los 101.108 +corchetes y el texto con la expansión de lo que sea está adentro. 101.109 +Para imprimir un corchete de forma literal, debe escaparlo, como se 101.110 +describe en la sección~\ref{sec:template:escape}. 101.111 + 101.112 +\section{Palabras claves más comunes en las plantillas} 101.113 +\label{sec:template:keyword} 101.114 + 101.115 +Puede empezar a escribir plantillas sencillas rápidamente con las 101.116 +palabras claves descritas a continuación: 101.117 + 101.118 +\begin{itemize} 101.119 +\item[\tplkword{author}] Cadena. El autor NO modificado del conjunto 101.120 + de cambios. 101.121 +\item[\tplkword{branches}] Cadena. El nombre de la rama en la cual se 101.122 + consignó el conjunto de cambios. Será vacía si el nombre de la rama es 101.123 + \texttt{default}. 101.124 +\item[\tplkword{date}] Información de fecha. La fecha en la cual se 101.125 + consignó el conjunto de cambios. \emph{No} es legible por un 101.126 + humano, debe pasarla por un firltro que la desplegará 101.127 + apropiadamente. En la sección~\ref{sec:template:filter} hay más 101.128 + detalles acerca de filtros. La fecha se expresa como un par de 101.129 + números. El primer número corresponde a una marca de tiempo UNIX 101.130 + UTC (segundos desde el primero de enero de 1970); la segunda es el 101.131 + corrimiento horario de la zona horaria del UTC en la cual se encontraba 101.132 + quien hizo la consignación, en segundos. 101.133 +\item[\tplkword{desc}] Cadena. La descripción en texto del conjunto 101.134 + de cambios. 101.135 +\item[\tplkword{files}] Lista de cadenas. Todos los ficheros 101.136 + modificados, adicionados o eliminados por este conjunto de cambios. 101.137 +\item[\tplkword{file\_adds}] Lista de cadenas. Ficheros adicionados 101.138 + por este conjunto de cambios. 101.139 +\item[\tplkword{file\_dels}] Lista de cadenas. Ficheros eliminados 101.140 + por este conjunto de cambios. 101.141 +\item[\tplkword{node}] Cadena. El hash de identificación de este 101.142 + conjunto de cambios como una cadena hexadecimal de 40 caracteres. 101.143 +\item[\tplkword{parents}] Lista de cadenas. Los ancestros del 101.144 + conjunto de cambios. 101.145 +\item[\tplkword{rev}] Entero. El número de revisión del repositorio 101.146 + local. 101.147 +\item[\tplkword{tags}] Lista de cadenas. Todas las etiquetas 101.148 + asociadas al conjunto de cambios. 101.149 +\end{itemize} 101.150 + 101.151 +Unos experimentos sencillos nos mostrarán qué esperar cuando usamos 101.152 +estas palabras claves; puede ver los resultados en la 101.153 +figura~\ref{fig:template:keywords}. 101.154 + 101.155 +\begin{figure} 101.156 + \interaction{template.simple.keywords} 101.157 + \caption{Template keywords in use} 101.158 + \label{fig:template:keywords} 101.159 +\end{figure} 101.160 + 101.161 +Como mencionamos anteriormente, la palabra clave de fecha no produce 101.162 +salida legible por un humano, debemos tratarla de forma especial. 101.163 +Esto involucra usar un \emph{filtro}, acerca de lo cual hay más en la 101.164 +sección~\ref{sec:template:filter}. 101.165 + 101.166 +\interaction{template.simple.datekeyword} 101.167 + 101.168 +\section{Secuencias de Control} 101.169 +\label{sec:template:escape} 101.170 + 101.171 +El motor de plantillas de Mercurial reconoce las secuencias de control 101.172 +más comunmente usadas dentro de las cadenas. Cuando ve un backslash 101.173 +(``\Verb+\+''), ve el caracter siguiente y sustituye los dos 101.174 +caracteres con un reemplazo sencillo, como se describe a continuación: 101.175 + 101.176 +\begin{itemize} 101.177 +\item[\Verb+\textbackslash\textbackslash+] Backslash, ``\Verb+\+'', 101.178 + ASCII~134. 101.179 +\item[\Verb+\textbackslash n+] Nueva línea, ASCII~12. 101.180 +\item[\Verb+\textbackslash r+] Cambio de línea, ASCII~15. 101.181 +\item[\Verb+\textbackslash t+] Tab, ASCII~11. 101.182 +\item[\Verb+\textbackslash v+] Tab Vertical, ASCII~13. 101.183 +\item[\Verb+\textbackslash \{+] Corchete abierto, ``\Verb+{+'', ASCII~173. 101.184 +\item[\Verb+\textbackslash \}+] Corchete cerrado, ``\Verb+}+'', ASCII~175. 101.185 +\end{itemize} 101.186 + 101.187 +Como se indicó arriba, si desea que la expansión en una plantilla 101.188 +contenga un caracter literal ``\Verb+\+'', ``\Verb+{+'', o 101.189 + ``\Verb+{+'', debe escaparlo. 101.190 + 101.191 +\section{Uso de filtros con palabras claves} 101.192 +\label{sec:template:filter} 101.193 + 101.194 +Algunos de los resultados de la expansión de la plantilla no son 101.195 +fáciles de usar de inmediato. Mercurial le permite especificar una 101.196 +cadena de \emph{filtros} opcionales para modificar el resultado de 101.197 +expandir una palabra clave. Ya ha visto el filtro usual 101.198 +\tplkwfilt{date}{isodate} en acción con anterioridad para hacer 101.199 +legible la fecha. 101.200 + 101.201 +A continuación hay una lista de los filtros de Mercurial más 101.202 +comunmente usados. Ciertos filtros pueden aplicarse a cualquier 101.203 +texto, otros pueden usarse únicamente en circunstancias específicas. 101.204 +El nombre de cada filtro está seguido de la indicación de dónde puede 101.205 +ser usado y una descripción de su efecto. 101.206 + 101.207 +\begin{itemize} 101.208 +\item[\tplfilter{addbreaks}] Cualquier texto. Añade una etiqueta XHTML 101.209 + ``\Verb+<br/>+'' antes del final de cada línea excepto en la final. 101.210 + Por ejemplo, ``\Verb+foo\nbar+'' se convierte en ``\Verb+foo<br/>\nbar+''. 101.211 +\item[\tplkwfilt{date}{age}] palabra clave \tplkword{date}. Muestra 101.212 + la edad de la fecha, relativa al tiempo actual. Ofrece una cadena como 101.213 + ``\Verb+10 minutes+''. 101.214 +\item[\tplfilter{basename}] Cualquier texto, pero de utilidad sobre 101.215 + todo en palabras claves relativas a \tplkword{ficheros}. Trata el 101.216 + texto como una ruta, retornando el nombre base. Por ejemplo, 101.217 + ``\Verb+foo/bar/baz+'', se convierte en ``\Verb+baz+''. 101.218 +\item[\tplkwfilt{date}{date}] \tplkword{date} palabra clave. Mostrar 101.219 + la fecha en un formato similar a la orden \tplkword{date} de 101.220 + in a similar format to the Unix, pero con la zona horaria incluída. 101.221 + Una cadena como ``\Verb+Mon Sep 04 15:13:13 2006 -0700+''. 101.222 +\item[\tplkwfilt{author}{domain}] Cualquier texto, pero de mayor 101.223 + utilidad para la palabra clave \tplkword{author}. Encuentra la 101.224 + primera cadena que luce como una dirección de correo electrónico, y 101.225 + extrae solamente el componente del dominio. Por ejemplo, de 101.226 + ``\Verb+Bryan O'Sullivan <bos@serpentine.com>+'' se extrae 101.227 + ``\Verb+serpentine.com+''. 101.228 +\item[\tplkwfilt{author}{email}] Cualquier texto, pero de mayor 101.229 + utilidad para la palabra clave \tplkword{author}. Extrae la primera 101.230 + cadena que luce como una dirección de correo. Por ejemplo, de 101.231 + ``\Verb+Bryan O'Sullivan <bos@serpentine.com>+'' extrae 101.232 + ``\Verb+bos@serpentine.com+''. 101.233 +\item[\tplfilter{escape}] Cualquier texto. Reemplaza los caracteres 101.234 + especiales de XML/XHTML: ``\Verb+&+'', ``\Verb+<+'' y ``\Verb+>+'' 101.235 + con las entidades XML. 101.236 +\item[\tplfilter{fill68}] Cualquier texto. Lograr que el texto ocupe 101.237 + las primeras 68 columnas. Es útil emplearlo antes de pasar el texto 101.238 + por el filtro \tplfilter{tabindent}, y queremos que aún quepa en una 101.239 + ventana de fuente fija y 80 columnas. 101.240 +\item[\tplfilter{fill76}] Cualquier texto. Lograr que el texto quepa 101.241 + en 76 columnas. 101.242 +\item[\tplfilter{firstline}] Cualquier texto. Mostrar la primera 101.243 + línea de texto sin saltos de línea. 101.244 +\item[\tplkwfilt{date}{hgdate}] \tplkword{date} palabra clave. 101.245 + Mostrar la fecha como un par de números legibles. Muestra una 101.246 + cadena como ``\Verb+1157407993 25200+''. 101.247 +\item[\tplkwfilt{date}{isodate}] \tplkword{date} palabra clave. 101.248 + Mostrar la fecha como una cadena de texto en el formato. Muestra 101.249 + una cadena como ``\Verb+2006-09-04 15:13:13 -0700+''. 101.250 +\item[\tplfilter{obfuscate}] Cualquier texto, pero de mayor utilidad 101.251 + para la palabra clave \tplkword{author}. Muestra el campo de texto 101.252 + como una secuencia de entidades XML. Esto ayuda a eliminar ciertos 101.253 + robots estúpidos de adquisición de correo. 101.254 +\item[\tplkwfilt{author}{person}] Cualquier texto, útil sobre todo 101.255 + para la palabra clave \tplkword{author}. Muestra el texto que hay 101.256 + antes de la dirección de correo electrónico. Por ejemplo, 101.257 + ``\Verb+Bryan O'Sullivan <bos@serpentine.com>+'' mostraría 101.258 + ``\Verb+Bryan O'Sullivan+''. 101.259 +\item[\tplkwfilt{date}{rfc822date}] \tplkword{date} palabra clave. 101.260 + Muestra una fecha con el mismo formato que se usa en los encabezados 101.261 + de correo. Mostraría una cadena como 101.262 + ``\Verb+Mon, 04 Sep 2006 15:13:13 -0700+''. 101.263 +\item[\tplkwfilt{node}{short}] Hash del conjunto de cambios. Muestra 101.264 + la forma corta de un hash de conjunto de cambios, 101.265 + of a changeset hash, p.e.~una cadena hexadecimal de 12 bytes. 101.266 +\item[\tplkwfilt{date}{shortdate}] \tplkword{date} palabra clave. 101.267 + Mostrar año, mes y día de una fecha. Muestrauna cadena como 101.268 + ``\Verb+2006-09-04+''. 101.269 +\item[\tplfilter{strip}] Cualquier texto. Elimina todos los espacios 101.270 + en blanco al principio y al final de la cadena. 101.271 +\item[\tplfilter{tabindent}] Cualquier texto. Muestra el texto con 101.272 + todas las líneas excepto la primera que comience con el caracter tab. 101.273 +\item[\tplfilter{urlescape}] Cualquier texto. Escapa todos los 101.274 + caracteres que se consideren como ``especiales'' por los parsers de 101.275 + URL. Por ejemplo, \Verb+foo bar+ se convierte en \Verb+foo%20bar+. 101.276 +\item[\tplkwfilt{author}{user}] Cualquier texto, útil sobre todo para 101.277 + la palabra clave \tplkword{author}. Retorna el ``usuario'' de una 101.278 + dirección de correo. Por ejemplo, 101.279 + ``\Verb+Bryan O'Sullivan <bos@serpentine.com>+'' se convierte en 101.280 + ``\Verb+bos+''. 101.281 +\end{itemize} 101.282 + 101.283 +\begin{figure} 101.284 + \interaction{template.simple.manyfilters} 101.285 + \caption{Filtros de plantilla en acción} 101.286 + \label{fig:template:filters} 101.287 +\end{figure} 101.288 + 101.289 +\begin{note} 101.290 + Si trata de aplicar un filtro a una porción de datos que no puede 101.291 + procesarse, Mercurial fallará e imprimirá una excepción de Python. 101.292 + Por ejemplo, el tratar de usar la salida de la palabra clave 101.293 + \tplkword{desc} con el filtro \tplkwfilt{date}{isodate} no resultará 101.294 + algo útil. 101.295 +\end{note} 101.296 + 101.297 +\subsection{Combinar filtros} 101.298 + 101.299 +Combinar filtros es para generar una salida en la forma como usted lo 101.300 +desea es muy sencillo. La cadena de filtros siguientes arman una 101.301 +descripción, después aseguran que cabe limpiamente en 68 columnas, y 101.302 +las indenta con 8~caracteres (por lo menos en sistemas tipo Unix, en 101.303 +los que el tab por convención se extiende en 8~caracteres). 101.304 + 101.305 +\interaction{template.simple.combine} 101.306 + 101.307 +Observe el uso de ``\Verb+\t+'' (un caracter tab) en la plantilla para 101.308 +forzar que la primera línea se indente; esto es necesario para lograr 101.309 +que la primera línea luzca indentada; es necesario debido a que 101.310 +\tplkword{tabindent} indenta todas las líneas \emph{excepto} la primera. 101.311 + 101.312 +Tenga en cuenta que el orden de los filtros importa. El primer filtro 101.313 +se aplica primero al resultado de la palabra clave; el segundo al 101.314 +resultado de la aplicación del primer filtro y así sucesivamente. Por 101.315 +ejemplo, usar \Verb+fill68|tabindent+ es muy distinto al resultado de 101.316 +usar \Verb+tabindent|fill68+. 101.317 + 101.318 + 101.319 +\section{De plantillas a estilos} 101.320 + 101.321 +Una plantilla provee una forma rápida y sencilla para dar formato a 101.322 +una salida. Las plantillas pueden volvers verbosas, y es útil poder 101.323 +darle un nombre a una plantilla. Un fichero de estilo es una 101.324 +plantilla con un nombre, almacenado en un fichero. 101.325 + 101.326 +Más aún, al usar un fichero de estilo se dispara el poder del motor de 101.327 +plantillas en un nivel imposible de alcanzar usando las opción 101.328 +\hgopt{log}{--template} desde la línea de órdenes. 101.329 + 101.330 + 101.331 +\subsection{Los ficheros de estilo más sencillos} 101.332 + 101.333 +Nuestro fichero sencillo de estilo contiene una sola línea: 101.334 + 101.335 +\interaction{template.simple.rev} 101.336 + 101.337 +Se le indica a Mercurial, ``si está imprimiendo un conjunto de 101.338 +cambios, use el texto de la derecha como la plantilla''. 101.339 + 101.340 +\subsection{Sintaxis de ficheros de estilo} 101.341 + 101.342 +Las reglas de sintaxis para un fichero de estilo son sencillas: 101.343 + 101.344 +\begin{itemize} 101.345 +\item El fichero se procesa línea por línea. 101.346 + 101.347 +\item Se ignoran el espacio en blanco circundante. 101.348 + 101.349 +\item Se omiten las líneas en blanco. 101.350 + 101.351 +\item Si una línea comienza con los caracteres ``\texttt{\#}'' o 101.352 + ``\texttt{;}'', la línea completa se trata como un comentario, y se 101.353 + omite como si fuera vacía. 101.354 + 101.355 +\item Una línea comienza con una palabra clave. Esta debe comenzar 101.356 + con una caracter alfabético o una raya al piso, y puede contener 101.357 + subsecuentemente cualquier caracter alfanumérico o una raya al 101.358 + piso. (En notación de expresiones regulares debe coincidir con 101.359 + \Verb+[A-Za-z_][A-Za-z0-9_]*+.) 101.360 + 101.361 +\item El próximo elemento debe ser un caracter ``\texttt{=}'', que 101.362 + puede estar precedido o seguido por una cantidad arbitraria de 101.363 + espacio. 101.364 + 101.365 +\item Si el resto de la línea comienza y termina con caracteres 101.366 + encerrados entre caracteres de comillas (bien sea sencillas o 101.367 + dobles), se trata como cuerpo de la plantilla. 101.368 + 101.369 +\item Si el resto de la línea \emph{no} comienza con una comilla, se 101.370 + trata como el nombre de un fichero; los contenidos de este fichero 101.371 + se leerán y se usarán como cuerpo de la plantilla. 101.372 +\end{itemize} 101.373 + 101.374 +\section{Ejemplos de ficheros de estilos} 101.375 + 101.376 +Para ilustrar la creación de un fichero de estilo, construiremos 101.377 +algunos ejemplos. En lugar de ofrecer un fichero completo de estilo y 101.378 +analizarlo, replicaremos el proceso usual de desarrollo de un fichero 101.379 +de estilo comenzando con algo muy sencillo, y avanzando por una serie 101.380 +de ejemplos sucesivos más completos. 101.381 + 101.382 +\subsection{Identificar equivocaciones en ficheros de estilo} 101.383 + 101.384 +Si Mercurial encuentra un problema en un fichero de estilo en el cual 101.385 +usted está trabajando, imprime un mensaje de error suscinto, cuando 101.386 +usted identifique lo que significa, resulta muy útil. 101.387 + 101.388 +\interaction{template.svnstyle.syntax.input} 101.389 + 101.390 +Tenga en cuenta que \filename{broken.style} trata de definir la 101.391 +palabra clave \texttt{changeset}, pero omite dar un contenido para esta. 101.392 +Cuando se le indica a Mercurial que use este fichero de estilo, se 101.393 +queja inmediatamente. 101.394 + 101.395 +\interaction{template.svnstyle.syntax.error} 101.396 + 101.397 +Este mensaje de error luce intimidante, pero no es muy difícil de 101.398 +seguir: 101.399 + 101.400 +\begin{itemize} 101.401 +\item El primer componente es la forma como Mercurial dice ``me rindo''. 101.402 + \begin{codesample4} 101.403 + \textbf{abort:} broken.style:1: parse error 101.404 + \end{codesample4} 101.405 + 101.406 +\item A continuación viene el nombre del fichero que contiene el error. 101.407 + \begin{codesample4} 101.408 + abort: \textbf{broken.style}:1: parse error 101.409 + \end{codesample4} 101.410 + 101.411 +\item Siguendo el nombre del fichero viene el número de línea en la 101.412 + que se encontró el error. 101.413 + \begin{codesample4} 101.414 + abort: broken.style:\textbf{1}: parse error 101.415 + \end{codesample4} 101.416 + 101.417 +\item Finalmente, la descripción de lo que falló. 101.418 + \begin{codesample4} 101.419 + abort: broken.style:1: \textbf{parse error} 101.420 + \end{codesample4} 101.421 + La descripción del problema no siempre es clara (como en este caso), 101.422 + pero aunque sea críptica, casi siempre es trivial la inspección 101.423 + visual de la línea en el fichero de estilo y encontrar lo que está 101.424 + mal. 101.425 +\end{itemize} 101.426 + 101.427 +\subsection{Identificar de forma única un repositorio} 101.428 + 101.429 +Si desea identificar un repositorio de Mercurial ``de forma única'' 101.430 +con una cadena corta como identificador, puede usar la primera 101.431 +revisión en el repositorio. 101.432 +\interaction{template.svnstyle.id} 101.433 +No es garantía de unicidad, pero no es útill en ciertos casos: 101.434 +many cases. 101.435 +\begin{itemize} 101.436 +\item No funcionará en un repositorio completamente vacío, porque un 101.437 + repositorio así no tiene una revisión~zero. 101.438 +\item Tampoco funcionará en caso (muy raro) cuando el repositorio sea 101.439 + una fusión de dos repositorios independientes y tiene los dos 101.440 + directorios por ahí. 101.441 +\end{itemize} 101.442 +Hay ciertos casos en los cuales podría colocar el identificador: 101.443 +\begin{itemize} 101.444 +\item Como una llave en la tabla de una base de datos que administra 101.445 + repositorios en un servidor. 101.446 +\item Como una parte del par \{\emph{ID~repositorio}, \emph{ID~revisión}\}. 101.447 + Almacene esta información de forma independiente cuando ejecute 101.448 + construcciones automatizadas u otras actividades, de forma que pueda 101.449 + ``reconstruir'' posteriormente en caso de ser necesario. 101.450 +\end{itemize} 101.451 + 101.452 +\subsection{Mostrando salida parecida a Subversion} 101.453 + 101.454 +Intentemos emular la salida usual que usa otro sistema de control de 101.455 +revisiones, Subversion. 101.456 +\interaction{template.svnstyle.short} 101.457 + 101.458 +Dado que la salida de Subversion es sencilla, es fácil copiar y pegar 101.459 +una porción de su salida en un fichero, y reemplazar el texto 101.460 +producido previamente por Subversion con valores base que quisiéramos 101.461 +ver expandidos. 101.462 +\interaction{template.svnstyle.template} 101.463 + 101.464 +Esta plantilla difiere en algunos detalles de la salida producida por 101.465 +Subversion: 101.466 +\begin{itemize} 101.467 +\item Subversion imprime una fecha ``legible'' (el ``\texttt{Wed, 27 Sep 101.468 + 2006}'' en el ejemplo de salida anterior) en paréntesis. El motor 101.469 + de plantillas de Mercurial no ofrece una forma sencilla de desplegar 101.470 + una fecha en este formato sin imprimir también la hora y la zona horaria. 101.471 +\item Emulamos las líneas de ``separación'' de subversion con caracteres 101.472 + ``\texttt{-}'' en una línea. Usamos la palabra clave 101.473 + \tplkword{header} del motor de plantillas para imprimir una línea de 101.474 + separación como la primera línea de salida (ver más abajo), para 101.475 + lograr una salida similara a la de Subversion. 101.476 +\item La salida de subversion incluye un conteo en el encabezado del 101.477 + número de líneas en el mensaje de consinación. No podemos 101.478 + replicarlo en Mercurial; el motor de plantilla no ofrece en la 101.479 + actualidad un filtro que cuente la cantidad de objetos que se le 101.480 + pasen. 101.481 +\end{itemize} 101.482 +No me tomó más de un minuto o dos de trabajo para reemplazar texto 101.483 +literal de un ejemplo de salida de la salida de Subversion con ciertas 101.484 +palabras claves y filtros para ofrecer la plantilla anterior. El 101.485 +fichero de estilo se refiere sencillamente a la plantilla. 101.486 +\interaction{template.svnstyle.style} 101.487 + 101.488 +Podríamos haber incluído el texto del fichero plantilla directamente 101.489 +en el fichero de estilo encerrando entre comillas y reemplazando las 101.490 +nuevas líneas con secuencias ``\verb!\n!'', pero haría muy difícil de 101.491 +leer el fichero de estilos. La facilidad para leer es importante 101.492 +cuando está decidiendo si un texto pertenece a un fichero de estilo o 101.493 +a un fichero de plantilla incluído en el estilo. Si el fichero de 101.494 +estilo luce muy grande o complicado, si inserta una pieza de texto 101.495 +literal, mejor colóquelo en una plantilla. 101.496 + 101.497 +%%% Local Variables: 101.498 +%%% mode: latex 101.499 +%%% TeX-master: "00book" 101.500 +%%% End:
102.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 102.2 +++ b/es/tour-basic.tex Thu Jan 29 22:00:07 2009 -0800 102.3 @@ -0,0 +1,690 @@ 102.4 +\chapter{Una gira de Mercurial: lo básico} 102.5 +\label{chap:tour-basic} 102.6 + 102.7 +\section{Instalar Mercurial en su sistema} 102.8 +\label{sec:tour:install} 102.9 +Hay paquetes binarios precompilados de Mercurial disponibles para cada 102.10 +sistema operativo popular. Esto hace fácil empezar a usar Mercurial 102.11 +en su computador inmediatamente. 102.12 + 102.13 +\subsection{Linux} 102.14 + 102.15 +Dado que cada distribución de Linux tiene sus propias herramientas de 102.16 +manejo de paquetes, políticas, y ritmos de desarrollo, es difícil dar 102.17 +un conjunto exhaustivo de instrucciones sobre cómo instalar el paquete 102.18 +de Mercurial. La versión de Mercurial que usted tenga a disposición 102.19 +puede variar dependiendo de qué tan activa sea la persona que mantiene 102.20 +el paquete para su distribución. 102.21 + 102.22 +Para mantener las cosas simples, me enfocaré en instalar Mercurial 102.23 +desde la línea de comandos en las distribuciones de Linux más 102.24 +populares. La mayoría de estas distribuciones proveen administradores 102.25 +de paquetes gráficos que le permitirán instalar Mercurial con un solo 102.26 +clic; el nombre de paquete a buscar es \texttt{mercurial}. 102.27 + 102.28 +\begin{itemize} 102.29 +\item[Debian] 102.30 + \begin{codesample4} 102.31 + apt-get install mercurial 102.32 + \end{codesample4} 102.33 + 102.34 +\item[Fedora Core] 102.35 + \begin{codesample4} 102.36 + yum install mercurial 102.37 + \end{codesample4} 102.38 + 102.39 +\item[Gentoo] 102.40 + \begin{codesample4} 102.41 + emerge mercurial 102.42 + \end{codesample4} 102.43 + 102.44 +\item[OpenSUSE] 102.45 + \begin{codesample4} 102.46 + yum install mercurial 102.47 + \end{codesample4} 102.48 + 102.49 +\item[Ubuntu] El paquete de Mercurial de Ubuntu está basado en el de 102.50 + Debian. Para instalarlo, ejecute el siguiente comando. 102.51 + \begin{codesample4} 102.52 + apt-get install mercurial 102.53 + \end{codesample4} 102.54 + El paquete de Mercurial para Ubuntu tiende a atrasarse con respecto 102.55 + a la versión de Debian por un margen de tiempo considerable 102.56 + (al momento de escribir esto, 7 meses), lo que en algunos casos 102.57 + significará que usted puede encontrarse con problemas que ya habrán 102.58 + sido resueltos en el paquete de Debian. 102.59 +\end{itemize} 102.60 + 102.61 +\subsection{Solaris} 102.62 + 102.63 +SunFreeWare, en \url{http://www.sunfreeware.com}, es una buena fuente 102.64 +para un gran número de paquetes compilados para Solaris para las 102.65 +arquitecturas Intel y Sparc de 32 y 64 bits, incluyendo versiones 102.66 +actuales de Mercurial. 102.67 + 102.68 +\subsection{Mac OS X} 102.69 + 102.70 +Lee Cantey publica un instalador de Mercurial para Mac OS~X en 102.71 +\url{http://mercurial.berkwood.com}. Este paquete funciona en tanto 102.72 +en Macs basados en Intel como basados en PowerPC. Antes de que pueda 102.73 +usarlo, usted debe instalar una versión compatible de Universal 102.74 +MacPython~\cite{web:macpython}. Esto es fácil de hacer; simplemente 102.75 +siga las instrucciones del sitio de Lee. 102.76 + 102.77 +También es posible instalar Mercurial usando Fink o MacPorts, dos 102.78 +administradores de paquetes gratuitos y populares para Mac OS X. Si 102.79 +usted tiene Fink, use \command{sudo apt-get install mercurial-py25}. 102.80 +Si usa MacPorts, \command{sudo port install mercurial}. 102.81 + 102.82 +\subsection{Windows} 102.83 + 102.84 +Lee Cantey publica un instalador de Mercurial para Windows en 102.85 +\url{http://mercurial.berkwood.com}. Este paquete no tiene 102.86 +% TODO traducción de it just works. Agreed? 102.87 +dependencias externas; ``simplemente funciona''. 102.88 + 102.89 +\begin{note} 102.90 + La versión de Windows de Mercurial no convierte automáticamente 102.91 + los fines de línea entre estilos Windows y Unix. Si usted desea 102.92 + compartir trabajo con usuarios de Unix, deberá hacer un trabajo 102.93 + adicional de configuración. XXX Terminar esto. 102.94 +\end{note} 102.95 + 102.96 +\section{Arrancando} 102.97 + 102.98 +Para empezar, usaremos el comando \hgcmd{version} para revisar si 102.99 +Mercurial está instalado adecuadamente. La información de la versión 102.100 +que es impresa no es tan importante; lo que nos importa es si imprime 102.101 +algo en absoluto. 102.102 + 102.103 +\interaction{tour.version} 102.104 + 102.105 +% TODO builtin-> integrado? 102.106 +\subsection{Ayuda integrada} 102.107 + 102.108 +Mercurial provee un sistema de ayuda integrada. Esto es invaluable 102.109 +para ésas ocasiones en la que usted está atorado tratando de recordar 102.110 +cómo ejecutar un comando. Si está completamente atorado, simplemente 102.111 +ejecute \hgcmd{help}; esto imprimirá una breve lista de comandos, 102.112 +junto con una descripción de qué hace cada uno. Si usted solicita 102.113 +ayuda sobre un comando específico (como abajo), se imprime información 102.114 +más detallada. 102.115 +\interaction{tour.help} 102.116 +Para un nivel más impresionante de detalle (que usted no va a 102.117 +necesitar usualmente) ejecute \hgcmdargs{help}{\hggopt{-v}}. La opción 102.118 +\hggopt{-v} es la abreviación para \hggopt{--verbose}, y le indica a 102.119 +Mercurial que imprima más información de lo que haría usualmente. 102.120 + 102.121 +\section{Trabajar con un repositorio} 102.122 + 102.123 +En Mercurial, todo sucede dentro de un \emph{repositorio}. El 102.124 +repositorio para un proyecto contiene todos los ficheros que 102.125 +``pertenecen a'' ése proyecto, junto con un registro histórico de los 102.126 +ficheros de ese proyecto. 102.127 + 102.128 +No hay nada particularmente mágico acerca de un repositorio; es 102.129 +simplemente un árbol de directorios en su sistema de ficheros que 102.130 +Mercurial trata como especial. Usted puede renombrar o borrar un 102.131 +repositorio en el momento que lo desee, usando bien sea la línea de 102.132 +comandos o su explorador de ficheros. 102.133 + 102.134 +\subsection{Hacer una copia local de un repositorio} 102.135 + 102.136 +\emph{Copiar} un repositorio es sólo ligeramente especial. Aunque 102.137 +usted podría usar un programa normal de copia de ficheros para hacer 102.138 +una copia del repositorio, es mejor usar el comando integrado que 102.139 +Mercurial ofrece. Este comando se llama \hgcmd{clone}\ndt{Del término 102.140 +``clonar'' en inglés.}, porque crea una copia idéntica de un 102.141 +repositorio existente. 102.142 +\interaction{tour.clone} 102.143 +Si nuestro clonado tiene éxito, deberíamos tener un directorio local 102.144 +llamado \dirname{hello}. Este directorio contendrá algunos ficheros. 102.145 +\interaction{tour.ls} 102.146 +Estos ficheros tienen el mismo contenido e historial en nuestro 102.147 +repositorio y en el repositorio que clonamos. 102.148 + 102.149 +Cada repositorio Mercurial está completo, es autocontenido e 102.150 +independiente. Contiene su propia copia de los ficheros y el historial 102.151 +de un proyecto. Un repositorio clonado recuerda la ubicación de la que 102.152 +fue clonado, pero no se comunica con ese repositorio, ni con ningún 102.153 +otro, a menos que usted le indique que lo haga. 102.154 + 102.155 +Lo que esto significa por ahora es que somos libres de experimentar 102.156 +con nuestro repositorio, con la tranquilidad de saber que es una 102.157 +% TODO figure out what to say instead of sandbox 102.158 +``caja de arena'' privada que no afectará a nadie más. 102.159 + 102.160 +\subsection{Qué hay en un repositorio?} 102.161 + 102.162 +Cuando miramos en detalle dentro de un repositorio, podemos ver que 102.163 +contiene un directorio llamado \dirname{.hg}. Aquí es donde Mercurial 102.164 +mantiene todos los metadatos del repositorio. 102.165 +\interaction{tour.ls-a} 102.166 + 102.167 +Los contenidos del directorio \dirname{.hg} y sus subdirectorios son 102.168 +exclusivos de Mercurial. Usted es libre de hacer lo que desee con 102.169 +cualquier otro fichero o directorio en el repositorio. 102.170 + 102.171 +Para introducir algo de terminología, el directorio \dirname{.hg} es 102.172 +el repositorio ``real'', y todos los ficheros y directorios que 102.173 +coexisten con él están en el \emph{directorio de trabajo}. Una forma 102.174 +sencilla de recordar esta distinción es que el \emph{repositorio} 102.175 +contiene el \emph{historial} de su proyecto, mientras que el 102.176 +\emph{directorio de trabajo} contiene una \emph{instantánea} de su 102.177 +proyecto en un punto particular del historial. 102.178 + 102.179 +\section{Vistazo rápido al historial} 102.180 + 102.181 +Una de las primeras cosas que se desea hacer con un repositorio nuevo, 102.182 +poco conocido, es conocer su historial. El comando \hgcmd{log} nos 102.183 +permite ver el mismo. 102.184 +\interaction{tour.log} 102.185 +Por defecto este programa imprime un párrafo breve por cada cambio al 102.186 +proyecto que haya sido grabado. Dentro de la terminología de 102.187 +Mercurial, cada uno de estos eventos es llamado \emph{conjunto de 102.188 +cambios}, porque pueden contener un registro de cambios a varios 102.189 +ficheros. 102.190 + 102.191 +Los campos de la salida de \hgcmd{log} son los siguientes. 102.192 +\begin{itemize} 102.193 + \item[\texttt{changeset}]\hspace{-0.5em}\ndt{Conjunto de cambios.} Este campo 102.194 + tiene un número, seguido por un 102.195 + % TODO digo mejor seguido por un dos puntos ? string => 102.196 + % cadena? 102.197 + \texttt{:}, seguido por una cadena hexadecimal. Ambos son 102.198 + \emph{identificadores} para el conjunto de cambios. Hay dos 102.199 + identificadores porque el número es más corto y más fácil de 102.200 + recordar que la cadena hexadecimal. 102.201 + 102.202 +\item[\texttt{user}]\hspace{-0.5em}\ndt{Usuario.} La identidad de la 102.203 + persona que creó el conjunto de cambios. Este es un campo en el 102.204 + que se puede almacenar cualquier valor, pero en la mayoría de los 102.205 + casos contiene el nombre de una persona y su dirección de correo 102.206 + electrónico. 102.207 + 102.208 +\item[\texttt{date}]\hspace{-0.5em}\ndt{Fecha.} La fecha y hora en la 102.209 + que el conjunto de cambios fue creado, y la zona horaria en la que 102.210 + fue creado. (La fecha y hora son locales a dicha zona horaria; 102.211 + ambos muestran la fecha y hora para la persona que creó el 102.212 + conjunto de cambios). 102.213 + 102.214 +\item[\texttt{summary}]\hspace{-0.5em}\ndt{Sumario.} 102.215 + La primera línea del texto que usó la persona que creó el conjunto 102.216 + de cambios para describir el mismo. 102.217 +\end{itemize} 102.218 +El texto impreso por \hgcmd{log} es sólo un sumario; omite una gran 102.219 +cantidad de detalles. 102.220 + 102.221 +La figura~\ref{fig:tour-basic:history} es una representación 102.222 +gráfica del historial del repositorio \dirname{hello}, para hacer más 102.223 +fácil ver en qué dirección está ``fluyendo'' el historial. Volveremos 102.224 +a esto varias veces en este capítulo y en los siguientes. 102.225 + 102.226 +\begin{figure}[ht] 102.227 + \centering 102.228 + \grafix{tour-history} 102.229 + \caption{Historial gráfico del repositorio \dirname{hello}} 102.230 + \label{fig:tour-basic:history} 102.231 +\end{figure} 102.232 + 102.233 +\subsection{Conjuntos de cambios, revisiones, y comunicándose con 102.234 +otras personas} 102.235 + 102.236 +%TODO sloppy => desordenado ? TODO hablar del inglés? o de español? 102.237 +Ya que el inglés es un lenguaje notablemente desordenado, y el área de 102.238 +ciencias de la computación tiene una notable historia de confusión de 102.239 +% TODO insertar ? al revés. no sé cómo en un teclado de estos. 102.240 +términos (porqué usar sólo un término cuando cuatro pueden servir?), 102.241 +el control de revisiones tiene una variedad de frases y palabras que 102.242 +tienen el mismo significado. Si usted habla acerca del historial de 102.243 +Mercurial con alguien, encontrará que la expresión ``conjunto de 102.244 +cambios'' es abreviada a menudo como ``cambio'' o (por escrito) 102.245 +``cset''\ndt{Abreviatura para la expresión ``changeset'' en inglés.}, 102.246 +y algunas veces un se hace referencia a un conjunto de cambios como 102.247 +una ``revisión'' o ``rev''\ndt{De nuevo, como abreviación para el 102.248 +término en inglés para ``revisión'' (``revision'').}. 102.249 + 102.250 +Si bien no es relevante qué \emph{palabra} use usted para referirse al 102.251 +concepto ``conjunto de cambios'', el \emph{identificador} que usted 102.252 +use para referise a ``un \emph{conjunto de cambios} particular'' es 102.253 +muy importante. Recuerde que el campo \texttt{changeset} en la salida 102.254 +de \hgcmd{log} identifica un conjunto de cambios usando tanto un 102.255 +número como una cadena hexadecimal. 102.256 + 102.257 +\begin{itemize} 102.258 + \item El número de revisión \emph{sólo es válido dentro del 102.259 + repositorio}. 102.260 + \item Por otro lado, la cadena hexadecimal es el 102.261 + \emph{identificador permanente e inmutable} que siempre 102.262 + identificará ése conjunto de cambios en \emph{todas} las 102.263 + copias del repositorio. 102.264 +\end{itemize} 102.265 +La diferencia es importante. Si usted le envía a alguien un correo 102.266 +electrónico hablando acerca de la ``revisión~33'', hay una 102.267 +probabilidad alta de que la revisión~33 de esa persona \emph{no sea la 102.268 +misma suya}. Esto sucede porque el número de revisión depende del 102.269 +orden en que llegan los cambios al repositorio, y no hay ninguna 102.270 +garantía de que los mismos cambios llegarán en el mismo orden en 102.271 +diferentes repositorios. Tres cambios dados $a,b,c$ pueden aparecer en 102.272 +un repositorio como $0,1,2$, mientras que en otro aparecen como 102.273 +$1,0,2$. 102.274 + 102.275 +Mercurial usa los números de revisión simplemente como una abreviación 102.276 +conveniente. Si usted necesita hablar con alguien acerca de un 102.277 +conjunto de cambios, o llevar el registro de un conjunto de cambios 102.278 +por alguna otra razón (por ejemplo, en un reporte de fallo), use el 102.279 +identificador hexadecimal. 102.280 + 102.281 +\subsection{Ver revisiones específicas} 102.282 + 102.283 +Para reducir la salida de \hgcmd{log} a una sola revisión, use la 102.284 +opción \hgopt{log}{-r} (o \hgopt{log}{--rev}). Puede usar un número 102.285 +de revisión o un identificador hexadecimal de conjunto de cambios, y 102.286 +puede pasar tantas revisiones como desee. 102.287 + 102.288 +\interaction{tour.log-r} 102.289 + 102.290 +Si desea ver el historial de varias revisiones sin tener que mencionar 102.291 +cada una de ellas, puede usar la \emph{notación de rango}; esto le 102.292 +permite expresar el concepto ``quiero ver todas las revisiones entre 102.293 +$a$ y $b$, inclusive''. 102.294 +\interaction{tour.log.range} 102.295 +Mercurial también respeta el orden en que usted especifica las 102.296 +revisiones, así que \hgcmdargs{log}{-r 2:4} muestra $2,3,4$ mientras 102.297 +que \hgcmdargs{log}{-r 4:2} muestra $4,3,2$. 102.298 + 102.299 +\subsection{Información más detallada} 102.300 +Aunque la información presentada por \hgcmd{log} es útil si usted sabe 102.301 +de antemano qué está buscando, puede que necesite ver una descripción 102.302 +completa del cambio, o una lista de los ficheros que cambiaron, si 102.303 +está tratando de averiguar si un conjunto de cambios dado es el que 102.304 +usted está buscando. La opción \hggopt{-v} (or \hggopt{--verbose}) del 102.305 +comando \hgcmd{log} le da este nivel extra de detalle. 102.306 +\interaction{tour.log-v} 102.307 + 102.308 +Si desea ver tanto la descripción como el contenido de un cambio, 102.309 +añada la opción \hgopt{log}{-p} (o \hgopt{log}{--patch}). Esto muestra 102.310 +% TODO qué hacemos con diff unificado? convervarlo, por ser la 102.311 +% acepción usual? 102.312 +el contenido de un cambio como un \emph{diff unificado} (si usted 102.313 +nunca ha visto un diff unificado antes, vea la 102.314 +sección~\ref{sec:mq:patch} para un vistazo global). 102.315 +\interaction{tour.log-vp} 102.316 + 102.317 +\section{Todo acerca de las opciones para comandos} 102.318 + 102.319 +Tomemos un breve descanso de la tarea de explorar los comandos de 102.320 +Mercurial para hablar de un patrón en la manera en que trabajan; será 102.321 +útil tener esto en mente a medida que avanza nuestra gira. 102.322 + 102.323 +Mercurial tiene un enfoque directo y consistente en el manejo de las 102.324 +opciones que usted le puede pasar a los comandos. Se siguen las 102.325 +convenciones para opciones que son comunes en sistemas Linux y Unix 102.326 +modernos. 102.327 +\begin{itemize} 102.328 +\item Cada opción tiene un nombre largo. Por ejemplo, el comando 102.329 + \hgcmd{log} acepta la opción \hgopt{log}{--rev}, como ya hemos 102.330 + visto. 102.331 +\item Muchas opciones tienen también un nombre corto. En vez de 102.332 + \hgopt{log}{--rev}, podemos usar \hgopt{log}{-r}. (El motivo para 102.333 + que algunas opciones no tengan nombres cortos es que dichas 102.334 + opciones se usan rara vez.) 102.335 +\item Las opciones largas empiezan con dos guiones (p.ej.~\hgopt{log}{--rev}), 102.336 + mientras que las opciones cortas empiezan con uno (e.g.~\hgopt{log}{-r}). 102.337 +\item El nombre y uso de las opciones es consistente en todos los 102.338 + comandos. Por ejemplo, cada comando que le permite pasar un ID de 102.339 + conjunto de cambios o un número de revisión acepta tanto la opción 102.340 + \hgopt{log}{-r} como la \hgopt{log}{--rev}. 102.341 +\end{itemize} 102.342 +En los ejemplos en este libro, uso las opciones cortas en vez de las 102.343 +largas. Esto sólo muestra mis preferencias, así que no le dé 102.344 +significado especial a eso. 102.345 + 102.346 +Muchos de los comandos que generan salida de algún tipo mostrarán más 102.347 +salida cuando se les pase la opción \hggopt{-v} (o 102.348 +\hggopt{--verbose}\ndt{Prolijo.}), y menos cuando se les pase la opción \hggopt{-q} 102.349 +(o \hggopt{--quiet}\ndt{Silencioso.}). 102.350 + 102.351 +\section{Hacer y repasar cambios} 102.352 + 102.353 +Ahora que tenemos una comprensión adecuada sobre cómo revisar el 102.354 +historial en Mercurial, hagamos algunos cambios y veamos cómo 102.355 +examinarlos. 102.356 + 102.357 +Lo primero que haremos será aislar nuestro experimento en un 102.358 +repositorio propio. Usaremos el comando \hgcmd{clone}, pero no hace 102.359 +falta clonar una copia del repositorio remoto. Como ya contamos con 102.360 +una copia local del mismo, podemos clonar esa. Esto es mucho más 102.361 +rápido que clonar a través de la red, y en la mayoría de los casos 102.362 +clonar un repositorio local usa menos espacio en disco también. 102.363 +\interaction{tour.reclone} 102.364 +A manera de recomendación, es considerado buena práctica mantener una 102.365 +copia ``prístina'' de un repositorio remoto a mano, del cual usted 102.366 +puede hacer clones temporales para crear cajas de arena para cada 102.367 +tarea en la que desee trabajar. Esto le permite trabajar en múltiples 102.368 +tareas en paralelo, teniendo cada una de ellas aislada de las otras 102.369 +hasta que estén completas y usted esté listo para integrar los cambios 102.370 +de vuelta. Como los clones locales son tan baratos, clonar y destruir 102.371 +repositorios no consume demasiados recursos, lo que facilita hacerlo 102.372 +en cualquier momento. 102.373 + 102.374 +En nuestro repositorio \dirname{my-hello}, hay un fichero 102.375 +\filename{hello.c} que contiene el clásico programa ``hello, 102.376 +world''\ndt{Hola, mundo.}. Usaremos el clásico y venerado comando 102.377 +\command{sed} para editar este fichero y hacer que imprima una segunda 102.378 +línea de salida. (Estoy usando el comando \command{sed} para hacer 102.379 +esto sólo porque es fácil escribir un ejemplo automatizado con él. 102.380 +Dado que usted no tiene esta restricción, probablemente no querrá usar 102.381 +\command{sed}; use su editor de texto preferido para hacer lo mismo). 102.382 +\interaction{tour.sed} 102.383 + 102.384 +El comando \hgcmd{status} de Mercurial nos dice lo que Mercurial sabe 102.385 +acerca de los ficheros en el repositorio. 102.386 +\interaction{tour.status} 102.387 +El comando \hgcmd{status} no imprime nada para algunos ficheros, sólo 102.388 +una línea empezando con ``\texttt{M}'' para el fichero 102.389 +\filename{hello.c}. A menos que usted lo indique explícitamente, 102.390 +\hgcmd{status} no imprimirá nada respecto a los ficheros que no han 102.391 +sido modificados. 102.392 + 102.393 +La ``\texttt{M}'' indica que Mercurial se dio cuenta de que nosotros 102.394 +modificamos \filename{hello.c}. No tuvimos que \emph{decirle} a 102.395 +Mercurial que íbamos a modificar ese fichero antes de hacerlo, o que 102.396 +lo modificamos una vez terminamos de hacerlo; él fue capaz de darse 102.397 +cuenta de esto por sí mismo. 102.398 + 102.399 +Es algo útil saber que hemos modificado el fichero \filename{hello.c}, 102.400 +pero preferiríamos saber exactamente \emph{qué} cambios hicimos. 102.401 +Para averiguar esto, usamos el comando \hgcmd{diff}. 102.402 +\interaction{tour.diff} 102.403 + 102.404 +\section{Grabar cambios en un nuevo conjunto de cambios} 102.405 + 102.406 +Podemos modificar, compilar y probar nuestros cambios, y usar 102.407 +\hgcmd{status} y \hgcmd{diff} para revisar los mismos, hasta que 102.408 +estemos satisfechos con los resultados y lleguemos a un momento en el 102.409 +que sea natural que querramos guardar nuestro trabajo en un nuevo 102.410 +conjunto de cambios. 102.411 + 102.412 +El comando \hgcmd{commit} nos permite crear un nuevo conjunto de 102.413 +cambios. Nos referiremos usualmente a esto como ``hacer una consigna'' 102.414 +o consignar. 102.415 + 102.416 +\subsection{Definir un nombre de usuario} 102.417 + 102.418 +Cuando usted trata de ejecutar \hgcmd{commit}\ndt{Hacer una 102.419 +consignación} por primera vez, no está garantizado que lo logre. 102.420 +Mercurial registra su nombre y dirección en cada cambio que usted 102.421 +consigna, para que más adelante otros puedan saber quién es el 102.422 +responsable de cada cambio. Mercurial trata de encontrar un nombre de 102.423 +% TODO consigna o consignación? 102.424 +usuario adecuado con el cual registrar la consignación. Se intenta con 102.425 +cada uno de los siguientes métodos, en el orden presentado. 102.426 +\begin{enumerate} 102.427 +\item Si usted pasa la opción \hgopt{commit}{-u} al comando \hgcmd{commit} 102.428 + en la línea de comandos, seguido de un nombre de usuario, se le da a 102.429 + esto la máxima precedencia. 102.430 +\item A continuación se revisa si usted ha definido la variable de 102.431 + entorno \envar{HGUSER}. 102.432 +\item Si usted crea un fichero en su directorio personal llamado 102.433 + \sfilename{.hgrc}, con una entrada \rcitem{ui}{username}, se usa 102.434 + luego. Para revisar cómo debe verse este fichero, refiérase a la 102.435 + sección~\ref{sec:tour-basic:username} más abajo. 102.436 +\item Si usted ha definido la variable de entorno \envar{EMAIL}, será 102.437 + usada a continuación. 102.438 +\item Mercurial le pedirá a su sistema buscar su nombre de usuario 102.439 + % TODO host => máquina 102.440 + local, y el nombre de máquina, y construirá un nombre de usuario a 102.441 + partir de estos componentes. Ya que esto generalmente termina 102.442 + generando un nombre de usuario no muy útil, se imprimirá una 102.443 + advertencia si es necesario hacerlo. 102.444 +\end{enumerate} 102.445 +Si todos estos procedimientos fallan, Mercurial fallará, e imprimirá 102.446 +un mensaje de error. En este caso, no le permitirá hacer la 102.447 +consignación hasta que usted defina un nombre de usuario. 102.448 + 102.449 +Trate de ver la variable de entorno \envar{HGUSER} y la opción 102.450 +\hgopt{commit}{-u} del comando \hgcmd{commit} como formas de 102.451 +\emph{hacer caso omiso} de la selección de nombre de usuario que 102.452 +Mercurial hace normalmente. Para uso normal, la manera más simple y 102.453 +sencilla de definir un nombre de usuario para usted es crear un 102.454 +fichero \sfilename{.hgrc}; los detalles se encuentran más adelante. 102.455 + 102.456 +\subsubsection{Crear el fichero de configuración de Mercurial} 102.457 +\label{sec:tour-basic:username} 102.458 + 102.459 +Para definir un nombre de usuario, use su editor de texto favorito 102.460 +para crear un fichero llamado \sfilename{.hgrc} en su directorio 102.461 +personal. Mercurial usará este fichero para obtener las 102.462 +configuraciones personalizadas que usted haya hecho. El contenido 102.463 +inicial de su fichero \sfilename{.hgrc} debería verse así. 102.464 +\begin{codesample2} 102.465 + # Este es un fichero de configuración de Mercurial. 102.466 + [ui] 102.467 + username = Primernombre Apellido <correo.electronico@dominio.net> 102.468 +\end{codesample2} 102.469 +La línea ``\texttt{[ui]}'' define una \emph{section} del fichero de 102.470 +configuración, así que usted puede leer la línea ``\texttt{username = 102.471 +...}'' como ``defina el valor del elemento \texttt{username} en la 102.472 +sección \texttt{ui}''. 102.473 +Una sección continua hasta que empieza otra nueva, o se llega al final 102.474 +del fichero. Mercurial ignora las líneas vacías y considera cualquier 102.475 +texto desde el caracter ``\texttt{\#}'' hasta el final de la línea 102.476 +como un comentario. 102.477 + 102.478 +\subsubsection{Escoger un nombre de usuario} 102.479 + 102.480 +Usted puede usar el texto que desee como el valor del campo de 102.481 +configuración \texttt{username}, ya que esta información será leída 102.482 +por otras personas, e interpretada por Mercurial. La convención que 102.483 +sigue la mayoría de la gente es usar su nombre y dirección de correo, 102.484 +como en el ejemplo anterior. 102.485 + 102.486 +\begin{note} 102.487 + % TODO web 102.488 + El servidor web integrado de Mercurial ofusca las direcciones de 102.489 + correo, para dificultar la tarea de las herramientas de 102.490 + recolección de direcciones de correo que usan los 102.491 + spammers\ndt{Personas que envían correo no solicitado, también 102.492 + conocido como correo basura}. Esto reduce la probabilidad de que 102.493 + usted empiece a recibir más correo basura si publica un 102.494 + repositorio en la red. 102.495 +\end{note} 102.496 + 102.497 +\subsection{Escribir un mensaje de consignación} 102.498 + 102.499 +Cuando consignamos un cambio, Mercurial nos ubica dentro de un editor 102.500 +de texto, para ingresar un mensaje que describa las modificaciones que 102.501 +hemos introducido en este conjunto de cambios. Esto es conocido como 102.502 +un \emph{mensaje de consignación}. Será un registro de lo que hicimos 102.503 +y porqué lo hicimos, y será impreso por \hgcmd{log} una vez hayamos 102.504 +hecho la consignación. 102.505 +\interaction{tour.commit} 102.506 + 102.507 +El editor en que \hgcmd{commit} nos ubica contendrá una línea vacía, 102.508 +seguida de varias líneas que empiezan con la cadena ``\texttt{HG:}''. 102.509 +\begin{codesample2} 102.510 + \emph{línea vacía} 102.511 + HG: changed hello.c 102.512 +\end{codesample2} 102.513 +Mercurial ignora las líneas que empiezan con ``\texttt{HG:}''; sólo 102.514 +las usa para indicarnos para cuáles ficheros está registrando los 102.515 +cambios. Modificar o borrar estas líneas no tiene ningún efecto. 102.516 + 102.517 +\subsection{Escribir un buen mensaje de consignación} 102.518 + 102.519 +Ya que por defecto \hgcmd{log} sólo muestra la primera línea de un 102.520 +mensaje de consignación, lo mejor es escribir un mensaje cuya primera 102.521 +línea tenga significado por sí misma. A continuación se encuentra un 102.522 +ejemplo de un mensaje de consignación que \emph{no} sigue esta 102.523 +pauta, y debido a ello tiene un sumario que no es legible. 102.524 +\begin{codesample2} 102.525 + changeset: 73:584af0e231be 102.526 + user: Persona Censurada <persona.censurada@ejemplo.org> 102.527 + date: Tue Sep 26 21:37:07 2006 -0700 102.528 + summary: se incluye buildmeister/commondefs. Añade un módulo 102.529 +\end{codesample2} 102.530 + 102.531 +Con respecto al resto del contenido del mensaje de consignación, no 102.532 +hay reglas estrictas-y-rápidas. Mercurial no interpreta ni le da 102.533 +importancia a los contenidos del mensaje de consignación, aunque es 102.534 +posible que su proyecto tenga políticas que definan una manera 102.535 +particular de escribirlo. 102.536 + 102.537 +Mi preferencia personal es usar mensajes de consignación cortos pero 102.538 +informativos, que me digan algo que no puedo inferir con una mirada 102.539 +rápida a la salida de \hgcmdargs{log}{--patch}. 102.540 + 102.541 +\subsection{Cancelar una consignación} 102.542 + 102.543 +Si usted decide que no desea hacer la consignación mientras está 102.544 +editando el mensaje de la misma, simplemente cierre su editor sin 102.545 +guardar los cambios al fichero que está editando. Esto hará que no 102.546 +pase nada ni en el repositorio ni en el directorio de trabajo. 102.547 + 102.548 +Si ejecutamos el comando \hgcmd{commit} sin ningún argumento, se 102.549 +registran todos los cambios que hemos hecho, como lo indican 102.550 +\hgcmd{status} y \hgcmd{diff}. 102.551 + 102.552 +\subsection{Admirar nuestro trabajo} 102.553 + 102.554 +Una vez hemos terminado la consignación, podemos usar el comando 102.555 +\hgcmd{tip}\ndt{Punta.} para mostrar el conjunto de cambios que acabamos de crear. 102.556 +La salida de este comando es idéntica a la de \hgcmd{log}, pero sólo 102.557 +muestra la revisión más reciente en el repositorio. 102.558 +\interaction{tour.tip} 102.559 +Nos referimos a la revisión más reciente en el repositorio como la 102.560 +revisión de punta, o simplemente la punta. 102.561 + 102.562 +\section{Compartir cambios} 102.563 + 102.564 +Anteriormente mencionamos que los repositorios en Mercurial están auto 102.565 +contenidos. Esto quiere decir que el conjunto de cambios que acabamos 102.566 +de crear sólo existe en nuestro repositorio \dirname{my-hello}. Veamos 102.567 +unas cuantas formas de propagar este cambio a otros repositorios. 102.568 + 102.569 +\subsection{Jalar cambios desde otro repositorio} 102.570 +\label{sec:tour:pull} 102.571 + 102.572 +Para empezar, clonemos nuestro repositorio \dirname{hello} original, 102.573 +el cual no contiene el cambio que acabamos de consignar. Llamaremos a 102.574 +este repositorio temporal \dirname{hello-pull}. 102.575 +\interaction{tour.clone-pull} 102.576 + 102.577 +Usaremos el comando \hgcmd{pull} para traer los cambios de 102.578 +\dirname{my-hello} y ponerlos en \dirname{hello-pull}. Sin embargo, 102.579 +traer cambios desconocidos y aplicarlos en un repositorio es una 102.580 +perspectiva que asusta al menos un poco. Mercurial cuenta con el 102.581 +comando \hgcmd{incoming}\ndt{Entrante, o cambios entrantes.} para 102.582 +decirnos qué cambios \emph{jalaría} el comando \hgcmd{pull} al 102.583 +repositorio, sin jalarlos. 102.584 +\interaction{tour.incoming} 102.585 +(Por supuesto, alguien podría enviar más conjuntos de cambios al 102.586 +repositorio en el tiempo que pasa entre la ejecución de 102.587 +\hgcmd{incoming} y la ejecución de \hgcmd{pull} para jalar los 102.588 +cambios, así que es posible que terminemos jalando cambios que no 102.589 +esperábamos.) 102.590 + 102.591 +Traer cambios al repositorio simplemente es cuestión de ejecutar el 102.592 +comando \hgcmd{pull}, indicándole de qué repositorio debe jalarlos. 102.593 +\interaction{tour.pull} 102.594 +Como puede verse por las salidas antes-y-después de \hgcmd{tip}, hemos 102.595 +jalado exitosamente los cambios en nuestro repositorio. Aún falta un 102.596 +paso para que podamos ver estos cambios en nuestro directorio de 102.597 +trabajo. 102.598 + 102.599 +\subsection{Actualizar el directorio de trabajo} 102.600 + 102.601 +Hasta ahora hemos pasado por alto la relación entre un repositorio y 102.602 +su directorio de trabajo. El comando \hgcmd{pull} que ejecutamos en la 102.603 +sección~\ref{sec:tour:pull} trajo los cambios al repositorio, pero si 102.604 +revisamos, no hay rastro de esos cambios en el directorio de trabajo. 102.605 +Esto pasa porque \hgcmd{pull} (por defecto) no modifica el directorio de 102.606 +trabajo. En vez de eso, usamos el comando 102.607 +\hgcmd{update}\ndt{Actualizar.} para hacerlo. 102.608 +\interaction{tour.update} 102.609 + 102.610 +Puede parecer algo raro que \hgcmd{pull} no actualice el directorio de 102.611 +trabajo automáticamente. De hecho, hay una buena razón para esto: 102.612 +usted puede usar \hgcmd{update} para actualizar el directorio de 102.613 +trabajo al estado en que se encontraba en \emph{cualquier revisión} 102.614 +del historial del repositorio. Si usted hubiera actualizado el 102.615 +directorio de trabajo a una revisión anterior---digamos, para buscar 102.616 +el origen de un fallo---y hubiera corrido un \hgcmd{pull} que hubiera 102.617 +actualizado el directorio de trabajo automáticamente a la nueva 102.618 +revisión, puede que no estuviera particularmente contento. 102.619 + 102.620 +Sin embargo, como jalar-y-actualizar es una secuencia de operaciones 102.621 +muy común, Mercurial le permite combinarlas al pasar la opción 102.622 +\hgopt{pull}{-u} 102.623 +a \hgcmd{pull}. 102.624 +\begin{codesample2} 102.625 + hg pull -u 102.626 +\end{codesample2} 102.627 +Si mira de vuelta la salida de \hgcmd{pull} en la 102.628 +sección~\ref{sec:tour:pull} cuando lo ejecutamos sin la opción \hgopt{pull}{-u}, 102.629 +verá que el comando imprimió un amable recordatorio de que tenemos que 102.630 +encargarnos explícitamente de actualizar el directorio de trabajo: 102.631 +\begin{codesample2} 102.632 + (run 'hg update' to get a working copy) 102.633 +\end{codesample2} 102.634 + 102.635 +Para averiguar en qué revisión se encuentra el directorio de trabajo, 102.636 +use el comando \hgcmd{parents}. 102.637 +\interaction{tour.parents} 102.638 +Si mira de nuevo la figura~\ref{fig:tour-basic:history}, verá flechas 102.639 +conectando cada conjunto de cambios. En cada caso, el nodo del que la flecha 102.640 +\emph{sale} es un padre, y el nodo al que la flecha \emph{llega} es 102.641 +su hijo. El directorio de trabajo tiene un padre exactamente de la 102.642 +misma manera; ése es el conjunto de cambios que contiene actualmente 102.643 +el directorio de trabajo. 102.644 + 102.645 +Para actualizar el conjunto de trabajo a una revisión particular, pase 102.646 +un número de revisión o un ID de conjunto de cambios al comando 102.647 +\hgcmd{update}. 102.648 +\interaction{tour.older} 102.649 +Si no indica explícitamente una revisión, \hgcmd{update} actualizará 102.650 +hasta la revisión de punta, como se vio en la segunda llamada a 102.651 +\hgcmd{update} en el ejemplo anterior. 102.652 + 102.653 +\subsection{Empujar cambios a otro repositorio} 102.654 + 102.655 +Mercurial nos permite empujar cambios a otro repositorio, desde el 102.656 +% TODO cambié "visitando" por "usando" 102.657 +repositorio que estemos usando actualmente. De la misma forma que en 102.658 +el ejemplo de \hgcmd{pull} arriba, crearemos un repositorio temporal 102.659 +para empujar allí nuestros cambios. 102.660 +\interaction{tour.clone-push} 102.661 +El comando \hgcmd{outgoing}\ndt{Saliente. Cambios salientes.} nos dice 102.662 +qué cambios serían empujados en el otro repositorio. 102.663 +\interaction{tour.outgoing} 102.664 +Y el comando \hgcmd{push} se encarga de empujar dichos cambios. 102.665 +\interaction{tour.push} 102.666 +Al igual que \hgcmd{pull}, el comando \hgcmd{push} no actualiza el 102.667 +directorio de trabajo del repositorio en el que estamos empujando los 102.668 +cambios. (A diferencia de \hgcmd{pull}, \hgcmd{push} no ofrece la 102.669 +opción \texttt{-u} para actualizar el directorio de trabajo del otro 102.670 +repositorio.) 102.671 + 102.672 +% TODO poner interrogante de apertura 102.673 +Qué pasa si tratamos de jalar o empujar cambios y el repositorio 102.674 +receptor ya tiene esos cambios? Nada emocionante. 102.675 +\interaction{tour.push.nothing} 102.676 + 102.677 +\subsection{Compartir cambios a través de una red} 102.678 + 102.679 +Los comandos que hemos presentando en las pocas secciones anteriores 102.680 +no están limitados a trabajar con repositorios locales. Cada uno de 102.681 +ellos funciona exactamente de la misma manera a través de una conexión 102.682 +% TODO poner ndt para URL 102.683 +de red. Simplemente pase una URL en vez de una ruta local. 102.684 +\interaction{tour.outgoing.net} 102.685 +En este ejemplo, podemos ver qué cambios empujaríamos al repositorio 102.686 +remoto, aunque, de manera entendible, el repositorio remoto está 102.687 +configurado para no permitir a usuarios anónimos empujar cambios a él. 102.688 +\interaction{tour.push.net} 102.689 + 102.690 +%%% Local Variables: 102.691 +%%% mode: latex 102.692 +%%% TeX-master: "00book" 102.693 +%%% End:
103.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 103.2 +++ b/es/tour-history.svg Thu Jan 29 22:00:07 2009 -0800 103.3 @@ -0,0 +1,298 @@ 103.4 +<?xml version="1.0" encoding="UTF-8" standalone="no"?> 103.5 +<!-- Created with Inkscape (http://www.inkscape.org/) --> 103.6 +<svg 103.7 + xmlns:dc="http://purl.org/dc/elements/1.1/" 103.8 + xmlns:cc="http://creativecommons.org/ns#" 103.9 + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 103.10 + xmlns:svg="http://www.w3.org/2000/svg" 103.11 + xmlns="http://www.w3.org/2000/svg" 103.12 + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" 103.13 + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" 103.14 + width="744.09448819" 103.15 + height="1052.3622047" 103.16 + id="svg2" 103.17 + sodipodi:version="0.32" 103.18 + inkscape:version="0.46" 103.19 + sodipodi:docname="tour-history.svg" 103.20 + inkscape:output_extension="org.inkscape.output.svg.inkscape"> 103.21 + <defs 103.22 + id="defs4"> 103.23 + <inkscape:perspective 103.24 + sodipodi:type="inkscape:persp3d" 103.25 + inkscape:vp_x="0 : 526.18109 : 1" 103.26 + inkscape:vp_y="0 : 1000 : 0" 103.27 + inkscape:vp_z="744.09448 : 526.18109 : 1" 103.28 + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" 103.29 + id="perspective2812" /> 103.30 + <marker 103.31 + inkscape:stockid="Arrow1Mstart" 103.32 + orient="auto" 103.33 + refY="0.0" 103.34 + refX="0.0" 103.35 + id="Arrow1Mstart" 103.36 + style="overflow:visible"> 103.37 + <path 103.38 + id="path2973" 103.39 + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " 103.40 + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none" 103.41 + transform="scale(0.4) translate(10,0)" /> 103.42 + </marker> 103.43 + <marker 103.44 + inkscape:stockid="Arrow1Mend" 103.45 + orient="auto" 103.46 + refY="0.0" 103.47 + refX="0.0" 103.48 + id="Arrow1Mend" 103.49 + style="overflow:visible;"> 103.50 + <path 103.51 + id="path3066" 103.52 + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " 103.53 + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;" 103.54 + transform="scale(0.4) rotate(180) translate(10,0)" /> 103.55 + </marker> 103.56 + </defs> 103.57 + <sodipodi:namedview 103.58 + id="base" 103.59 + pagecolor="#ffffff" 103.60 + bordercolor="#666666" 103.61 + borderopacity="1.0" 103.62 + gridtolerance="10000" 103.63 + guidetolerance="10" 103.64 + objecttolerance="10" 103.65 + inkscape:pageopacity="0.0" 103.66 + inkscape:pageshadow="2" 103.67 + inkscape:zoom="1.4" 103.68 + inkscape:cx="232.14286" 103.69 + inkscape:cy="672.75296" 103.70 + inkscape:document-units="px" 103.71 + inkscape:current-layer="layer1" 103.72 + inkscape:window-width="906" 103.73 + inkscape:window-height="659" 103.74 + inkscape:window-x="5" 103.75 + inkscape:window-y="49" 103.76 + showgrid="false" /> 103.77 + <metadata 103.78 + id="metadata7"> 103.79 + <rdf:RDF> 103.80 + <cc:Work 103.81 + rdf:about=""> 103.82 + <dc:format>image/svg+xml</dc:format> 103.83 + <dc:type 103.84 + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> 103.85 + </cc:Work> 103.86 + </rdf:RDF> 103.87 + </metadata> 103.88 + <g 103.89 + inkscape:label="Layer 1" 103.90 + inkscape:groupmode="layer" 103.91 + id="layer1"> 103.92 + <rect 103.93 + style="opacity:1;fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" 103.94 + id="rect1878" 103.95 + width="94.285713" 103.96 + height="20.714285" 103.97 + x="138" 103.98 + y="479.50504" /> 103.99 + <text 103.100 + xml:space="preserve" 103.101 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier" 103.102 + x="162.09892" 103.103 + y="493.12619" 103.104 + id="text1872"><tspan 103.105 + sodipodi:role="line" 103.106 + id="tspan1874" 103.107 + x="162.09892" 103.108 + y="493.12619" 103.109 + style="font-family:Courier"><tspan 103.110 + style="font-weight:bold" 103.111 + id="tspan1876">0</tspan>: REV0</tspan></text> 103.112 + <rect 103.113 + style="opacity:1;fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" 103.114 + id="rect2800" 103.115 + width="94.285713" 103.116 + height="20.714285" 103.117 + x="138" 103.118 + y="432.63004" /> 103.119 + <text 103.120 + xml:space="preserve" 103.121 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier" 103.122 + x="162.09892" 103.123 + y="446.25119" 103.124 + id="text2794"><tspan 103.125 + sodipodi:role="line" 103.126 + id="tspan2796" 103.127 + x="162.09892" 103.128 + y="446.25119" 103.129 + style="font-family:Courier"><tspan 103.130 + id="tspan2868" 103.131 + style="font-weight:bold">1</tspan>: REV1</tspan></text> 103.132 + <rect 103.133 + style="opacity:1;fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" 103.134 + id="rect2810" 103.135 + width="94.285713" 103.136 + height="20.714285" 103.137 + x="138" 103.138 + y="385.75504" /> 103.139 + <text 103.140 + xml:space="preserve" 103.141 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier" 103.142 + x="162.09892" 103.143 + y="399.37619" 103.144 + id="text2804"><tspan 103.145 + sodipodi:role="line" 103.146 + id="tspan2806" 103.147 + x="162.09892" 103.148 + y="399.37619" 103.149 + style="font-family:Courier"><tspan 103.150 + style="font-weight:bold" 103.151 + id="tspan2866">2</tspan>: REV2</tspan></text> 103.152 + <rect 103.153 + style="opacity:1;fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" 103.154 + id="rect2820" 103.155 + width="94.285713" 103.156 + height="20.714285" 103.157 + x="138" 103.158 + y="338.88007" /> 103.159 + <text 103.160 + xml:space="preserve" 103.161 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier" 103.162 + x="162.09892" 103.163 + y="352.50122" 103.164 + id="text2814"><tspan 103.165 + sodipodi:role="line" 103.166 + id="tspan2816" 103.167 + x="162.09892" 103.168 + y="352.50122" 103.169 + style="font-family:Courier"><tspan 103.170 + style="font-weight:bold" 103.171 + id="tspan2864">3</tspan>: REV3</tspan></text> 103.172 + <rect 103.173 + style="opacity:1;fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" 103.174 + id="rect2830" 103.175 + width="94.285713" 103.176 + height="20.714285" 103.177 + x="138" 103.178 + y="292.00504" /> 103.179 + <text 103.180 + xml:space="preserve" 103.181 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier" 103.182 + x="162.09892" 103.183 + y="305.62619" 103.184 + id="text2824"><tspan 103.185 + sodipodi:role="line" 103.186 + id="tspan2826" 103.187 + x="162.09892" 103.188 + y="305.62619" 103.189 + style="font-family:Courier"><tspan 103.190 + style="font-weight:bold" 103.191 + id="tspan2862">4</tspan>: REV4</tspan></text> 103.192 + <text 103.193 + xml:space="preserve" 103.194 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier" 103.195 + x="173.57143" 103.196 + y="443.79074" 103.197 + id="text2832"><tspan 103.198 + sodipodi:role="line" 103.199 + id="tspan2834" 103.200 + x="173.57143" 103.201 + y="443.79074" /></text> 103.202 + <path 103.203 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)" 103.204 + d="M 185.14286,478.50504 L 185.14286,454.34432" 103.205 + id="path2894" 103.206 + inkscape:connector-type="polyline" /> 103.207 + <path 103.208 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)" 103.209 + d="M 185.14286,431.63004 L 185.14286,407.46932" 103.210 + id="path2896" 103.211 + inkscape:connector-type="polyline" /> 103.212 + <path 103.213 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)" 103.214 + d="M 185.14286,384.75504 L 185.14286,360.59435" 103.215 + id="path2898" 103.216 + inkscape:connector-type="polyline" /> 103.217 + <path 103.218 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)" 103.219 + d="M 185.14286,337.88007 L 185.14286,313.71932" 103.220 + id="path2900" 103.221 + inkscape:connector-type="polyline" /> 103.222 + <text 103.223 + xml:space="preserve" 103.224 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times" 103.225 + x="244.60992" 103.226 + y="305.245" 103.227 + id="text1902"><tspan 103.228 + sodipodi:role="line" 103.229 + id="tspan1904" 103.230 + x="244.60992" 103.231 + y="305.245">(la más nueva)</tspan></text> 103.232 + <text 103.233 + xml:space="preserve" 103.234 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times" 103.235 + x="244.60992" 103.236 + y="492.745" 103.237 + id="text1906"><tspan 103.238 + sodipodi:role="line" 103.239 + id="tspan1908" 103.240 + x="244.60992" 103.241 + y="492.745">(la más antigua)</tspan></text> 103.242 + <rect 103.243 + style="opacity:1;fill:#d2e1e4;fill-opacity:1;stroke:#b1cbd0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" 103.244 + id="rect1907" 103.245 + width="94.285713" 103.246 + height="20.714285" 103.247 + x="309.28571" 103.248 + y="324.86218" /> 103.249 + <text 103.250 + xml:space="preserve" 103.251 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier" 103.252 + x="333.38464" 103.253 + y="338.48334" 103.254 + id="text1909"><tspan 103.255 + sodipodi:role="line" 103.256 + id="tspan1911" 103.257 + x="333.38464" 103.258 + y="338.48334" 103.259 + style="font-family:Courier"><tspan 103.260 + style="font-weight:bold" 103.261 + id="tspan1913">4</tspan>: REV4</tspan></text> 103.262 + <path 103.263 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" 103.264 + d="M 332.14286,375.21932 L 335.71429,347.36218" 103.265 + id="path2802" /> 103.266 + <path 103.267 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" 103.268 + d="M 372.69968,375.21932 L 369.12825,347.36218" 103.269 + id="path2986" /> 103.270 + <text 103.271 + xml:space="preserve" 103.272 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times" 103.273 + x="335.14285" 103.274 + y="387.21933" 103.275 + id="text2988"><tspan 103.276 + sodipodi:role="line" 103.277 + x="335.14285" 103.278 + y="387.21933" 103.279 + id="tspan3020" 103.280 + style="text-align:end;text-anchor:end">número de</tspan><tspan 103.281 + sodipodi:role="line" 103.282 + x="335.14285" 103.283 + y="402.21933" 103.284 + id="tspan3014" 103.285 + style="text-align:end;text-anchor:end">revisión</tspan></text> 103.286 + <text 103.287 + xml:space="preserve" 103.288 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times" 103.289 + x="368.71429" 103.290 + y="387.21933" 103.291 + id="text2994"><tspan 103.292 + sodipodi:role="line" 103.293 + id="tspan2996" 103.294 + x="368.71429" 103.295 + y="387.21933">identificador del</tspan><tspan 103.296 + sodipodi:role="line" 103.297 + x="368.71429" 103.298 + y="402.21933" 103.299 + id="tspan2998">conjunto de cambios</tspan></text> 103.300 + </g> 103.301 +</svg>
104.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 104.2 +++ b/es/tour-merge-conflict.svg Thu Jan 29 22:00:07 2009 -0800 104.3 @@ -0,0 +1,219 @@ 104.4 +<?xml version="1.0" encoding="UTF-8" standalone="no"?> 104.5 +<!-- Created with Inkscape (http://www.inkscape.org/) --> 104.6 +<svg 104.7 + xmlns:dc="http://purl.org/dc/elements/1.1/" 104.8 + xmlns:cc="http://creativecommons.org/ns#" 104.9 + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 104.10 + xmlns:svg="http://www.w3.org/2000/svg" 104.11 + xmlns="http://www.w3.org/2000/svg" 104.12 + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" 104.13 + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" 104.14 + width="744.09448819" 104.15 + height="1052.3622047" 104.16 + id="svg2" 104.17 + sodipodi:version="0.32" 104.18 + inkscape:version="0.46" 104.19 + sodipodi:docname="tour-merge-conflict.svg" 104.20 + inkscape:output_extension="org.inkscape.output.svg.inkscape"> 104.21 + <defs 104.22 + id="defs4"> 104.23 + <inkscape:perspective 104.24 + sodipodi:type="inkscape:persp3d" 104.25 + inkscape:vp_x="0 : 526.18109 : 1" 104.26 + inkscape:vp_y="0 : 1000 : 0" 104.27 + inkscape:vp_z="744.09448 : 526.18109 : 1" 104.28 + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" 104.29 + id="perspective2861" /> 104.30 + <marker 104.31 + inkscape:stockid="Arrow1Mend" 104.32 + orient="auto" 104.33 + refY="0.0" 104.34 + refX="0.0" 104.35 + id="Arrow1Mend" 104.36 + style="overflow:visible;"> 104.37 + <path 104.38 + id="path3053" 104.39 + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " 104.40 + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;" 104.41 + transform="scale(0.4) rotate(180) translate(10,0)" /> 104.42 + </marker> 104.43 + </defs> 104.44 + <sodipodi:namedview 104.45 + id="base" 104.46 + pagecolor="#ffffff" 104.47 + bordercolor="#666666" 104.48 + borderopacity="1.0" 104.49 + gridtolerance="10000" 104.50 + guidetolerance="10" 104.51 + objecttolerance="10" 104.52 + inkscape:pageopacity="0.0" 104.53 + inkscape:pageshadow="2" 104.54 + inkscape:zoom="1.4" 104.55 + inkscape:cx="251.65243" 104.56 + inkscape:cy="733.42197" 104.57 + inkscape:document-units="px" 104.58 + inkscape:current-layer="layer1" 104.59 + inkscape:window-width="906" 104.60 + inkscape:window-height="659" 104.61 + inkscape:window-x="5" 104.62 + inkscape:window-y="49" 104.63 + showgrid="false" /> 104.64 + <metadata 104.65 + id="metadata7"> 104.66 + <rdf:RDF> 104.67 + <cc:Work 104.68 + rdf:about=""> 104.69 + <dc:format>image/svg+xml</dc:format> 104.70 + <dc:type 104.71 + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> 104.72 + </cc:Work> 104.73 + </rdf:RDF> 104.74 + </metadata> 104.75 + <g 104.76 + inkscape:label="Layer 1" 104.77 + inkscape:groupmode="layer" 104.78 + id="layer1"> 104.79 + <g 104.80 + id="g1988" 104.81 + transform="translate(84.85711,0)"> 104.82 + <g 104.83 + id="g1876"> 104.84 + <path 104.85 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" 104.86 + d="M 118.57143,458.21933 L 118.57143,563.79075 L 191.42857,563.79075 L 204.28571,550.93361 L 203.57142,459.6479 L 118.57143,458.21933 z " 104.87 + id="path1872" 104.88 + sodipodi:nodetypes="cccccc" /> 104.89 + <path 104.90 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" 104.91 + d="M 191.55484,563.36862 L 191.6923,560.98794 L 192.69126,552.44884 L 203.80416,551.31242" 104.92 + id="path1874" 104.93 + sodipodi:nodetypes="cccc" /> 104.94 + </g> 104.95 + <flowRoot 104.96 + style="font-size:8px;font-family:Times New Roman" 104.97 + id="flowRoot1898" 104.98 + xml:space="preserve"><flowRegion 104.99 + id="flowRegion1900"><rect 104.100 + style="font-size:8px;font-family:Times New Roman" 104.101 + y="464.50504" 104.102 + x="122.85714" 104.103 + height="93.571426" 104.104 + width="76.428574" 104.105 + id="rect1902" /></flowRegion><flowPara 104.106 + id="flowPara1904">Saludos!</flowPara><flowPara 104.107 + id="flowPara1906" /><flowPara 104.108 + id="flowPara1908">Soy Mariam Abacha, la esposa del anterior dictador de Nigeria Sani Abacha. Le contacto en secreto, buscando los medios para desarrollar</flowPara></flowRoot> </g> 104.109 + <g 104.110 + id="g1966" 104.111 + transform="translate(82,0.35715)"> 104.112 + <g 104.113 + transform="translate(-77.85718,-140.0714)" 104.114 + id="g1910"> 104.115 + <path 104.116 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" 104.117 + d="M 118.57143,458.21933 L 118.57143,563.79075 L 191.42857,563.79075 L 204.28571,550.93361 L 203.57142,459.6479 L 118.57143,458.21933 z " 104.118 + id="path1912" 104.119 + sodipodi:nodetypes="cccccc" /> 104.120 + <path 104.121 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" 104.122 + d="M 191.55484,563.36862 L 191.6923,560.98794 L 192.69126,552.44884 L 203.80416,551.31242" 104.123 + id="path1914" 104.124 + sodipodi:nodetypes="cccc" /> 104.125 + </g> 104.126 + <flowRoot 104.127 + transform="translate(-77.85718,-140.0714)" 104.128 + style="font-size:8px;font-family:Times New Roman" 104.129 + id="flowRoot1916" 104.130 + xml:space="preserve"><flowRegion 104.131 + id="flowRegion1918"><rect 104.132 + style="font-size:8px;font-family:Times New Roman" 104.133 + y="464.50504" 104.134 + x="122.85714" 104.135 + height="93.571426" 104.136 + width="76.428574" 104.137 + id="rect1920" /></flowRegion><flowPara 104.138 + id="flowPara1922">Saludos!</flowPara><flowPara 104.139 + id="flowPara1924" /><flowPara 104.140 + id="flowPara1926">Soy <flowSpan 104.141 + style="font-style:italic;fill:#ff0000" 104.142 + id="flowSpan3094">Shehu Musa Abacha, sobrina del</flowSpan> anterior dictador de Nigeria Sani Abacha. Le contacto en secreto, buscando los medios para desarrollar</flowPara></flowRoot> </g> 104.143 + <g 104.144 + id="g1977" 104.145 + transform="translate(81.99999,-0.35715)"> 104.146 + <g 104.147 + transform="translate(83.57141,-139.3571)" 104.148 + id="g1932"> 104.149 + <path 104.150 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" 104.151 + d="M 118.57143,458.21933 L 118.57143,563.79075 L 191.42857,563.79075 L 204.28571,550.93361 L 203.57142,459.6479 L 118.57143,458.21933 z " 104.152 + id="path1934" 104.153 + sodipodi:nodetypes="cccccc" /> 104.154 + <path 104.155 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" 104.156 + d="M 191.55484,563.36862 L 191.6923,560.98794 L 192.69126,552.44884 L 203.80416,551.31242" 104.157 + id="path1936" 104.158 + sodipodi:nodetypes="cccc" /> 104.159 + </g> 104.160 + <flowRoot 104.161 + transform="translate(83.57141,-139.3571)" 104.162 + style="font-size:8px;font-family:Times New Roman" 104.163 + id="flowRoot1938" 104.164 + xml:space="preserve"><flowRegion 104.165 + id="flowRegion1940"><rect 104.166 + style="font-size:8px;font-family:Times New Roman" 104.167 + y="464.50504" 104.168 + x="122.85714" 104.169 + height="93.571426" 104.170 + width="76.428574" 104.171 + id="rect1942" /></flowRegion><flowPara 104.172 + id="flowPara1944">Saludos!</flowPara><flowPara 104.173 + id="flowPara1946" /><flowPara 104.174 + id="flowPara1948">Soy <flowSpan 104.175 + style="font-style:italic;fill:#ff0000" 104.176 + id="flowSpan3096">Alhaji Abba Abacha, hijo del</flowSpan> anterior dictador de Nigeria Sani Abacha. Le contacto en secreto, buscando los medios para desarrollar</flowPara></flowRoot> </g> 104.177 + <path 104.178 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" 104.179 + d="M 215.502,457.71933 L 196.35507,424.5765" 104.180 + id="path1999" 104.181 + inkscape:connector-type="polyline" 104.182 + inkscape:connection-start="#g1988" 104.183 + inkscape:connection-end="#g1966" /> 104.184 + <path 104.185 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" 104.186 + d="M 277.06936,457.71933 L 296.21629,424.5765" 104.187 + id="path2001" 104.188 + inkscape:connector-type="polyline" 104.189 + inkscape:connection-start="#g1988" 104.190 + inkscape:connection-end="#g1977" /> 104.191 + <text 104.192 + xml:space="preserve" 104.193 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 104.194 + x="302.42859" 104.195 + y="515.08905" 104.196 + id="text1905"><tspan 104.197 + sodipodi:role="line" 104.198 + id="tspan1907" 104.199 + x="302.42859" 104.200 + y="515.08905">Versión inicial</tspan></text> 104.201 + <text 104.202 + xml:space="preserve" 104.203 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 104.204 + x="30.57143" 104.205 + y="374.1619" 104.206 + id="text1917"><tspan 104.207 + sodipodi:role="line" 104.208 + id="tspan1919" 104.209 + x="30.57143" 104.210 + y="374.1619">Nuestros cambios</tspan></text> 104.211 + <text 104.212 + xml:space="preserve" 104.213 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 104.214 + x="385.71429" 104.215 + y="374.1619" 104.216 + id="text1921"><tspan 104.217 + sodipodi:role="line" 104.218 + id="tspan1923" 104.219 + x="385.71429" 104.220 + y="374.1619">Sus cambios</tspan></text> 104.221 + </g> 104.222 +</svg>
105.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 105.2 +++ b/es/tour-merge-merge.svg Thu Jan 29 22:00:07 2009 -0800 105.3 @@ -0,0 +1,389 @@ 105.4 +<?xml version="1.0" encoding="UTF-8" standalone="no"?> 105.5 +<!-- Created with Inkscape (http://www.inkscape.org/) --> 105.6 +<svg 105.7 + xmlns:dc="http://purl.org/dc/elements/1.1/" 105.8 + xmlns:cc="http://creativecommons.org/ns#" 105.9 + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 105.10 + xmlns:svg="http://www.w3.org/2000/svg" 105.11 + xmlns="http://www.w3.org/2000/svg" 105.12 + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" 105.13 + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" 105.14 + width="744.09448819" 105.15 + height="1052.3622047" 105.16 + id="svg2" 105.17 + sodipodi:version="0.32" 105.18 + inkscape:version="0.46" 105.19 + sodipodi:docname="tour-merge-merge.svg" 105.20 + inkscape:output_extension="org.inkscape.output.svg.inkscape"> 105.21 + <defs 105.22 + id="defs4"> 105.23 + <inkscape:perspective 105.24 + sodipodi:type="inkscape:persp3d" 105.25 + inkscape:vp_x="0 : 526.18109 : 1" 105.26 + inkscape:vp_y="0 : 1000 : 0" 105.27 + inkscape:vp_z="744.09448 : 526.18109 : 1" 105.28 + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" 105.29 + id="perspective2928" /> 105.30 + <marker 105.31 + inkscape:stockid="Arrow1Mstart" 105.32 + orient="auto" 105.33 + refY="0.0" 105.34 + refX="0.0" 105.35 + id="Arrow1Mstart" 105.36 + style="overflow:visible"> 105.37 + <path 105.38 + id="path2973" 105.39 + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " 105.40 + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none" 105.41 + transform="scale(0.4) translate(10,0)" /> 105.42 + </marker> 105.43 + <marker 105.44 + inkscape:stockid="Arrow1Mend" 105.45 + orient="auto" 105.46 + refY="0.0" 105.47 + refX="0.0" 105.48 + id="Arrow1Mend" 105.49 + style="overflow:visible;"> 105.50 + <path 105.51 + id="path3066" 105.52 + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " 105.53 + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;" 105.54 + transform="scale(0.4) rotate(180) translate(10,0)" /> 105.55 + </marker> 105.56 + </defs> 105.57 + <sodipodi:namedview 105.58 + id="base" 105.59 + pagecolor="#ffffff" 105.60 + bordercolor="#666666" 105.61 + borderopacity="1.0" 105.62 + gridtolerance="10000" 105.63 + guidetolerance="10" 105.64 + objecttolerance="10" 105.65 + inkscape:pageopacity="0.0" 105.66 + inkscape:pageshadow="2" 105.67 + inkscape:zoom="0.98994949" 105.68 + inkscape:cx="328.35015" 105.69 + inkscape:cy="790.24518" 105.70 + inkscape:document-units="px" 105.71 + inkscape:current-layer="layer1" 105.72 + inkscape:window-width="1278" 105.73 + inkscape:window-height="756" 105.74 + inkscape:window-x="0" 105.75 + inkscape:window-y="0" 105.76 + showgrid="false" /> 105.77 + <metadata 105.78 + id="metadata7"> 105.79 + <rdf:RDF> 105.80 + <cc:Work 105.81 + rdf:about=""> 105.82 + <dc:format>image/svg+xml</dc:format> 105.83 + <dc:type 105.84 + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> 105.85 + </cc:Work> 105.86 + </rdf:RDF> 105.87 + </metadata> 105.88 + <g 105.89 + inkscape:label="Layer 1" 105.90 + inkscape:groupmode="layer" 105.91 + id="layer1"> 105.92 + <rect 105.93 + style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" 105.94 + id="rect2995" 105.95 + width="94.285713" 105.96 + height="20.714285" 105.97 + x="532.85718" 105.98 + y="203.0479" /> 105.99 + <text 105.100 + xml:space="preserve" 105.101 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier" 105.102 + x="173.57143" 105.103 + y="443.79074" 105.104 + id="text2832"><tspan 105.105 + sodipodi:role="line" 105.106 + id="tspan2834" 105.107 + x="173.57143" 105.108 + y="443.79074" /></text> 105.109 + <rect 105.110 + style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" 105.111 + id="rect2830" 105.112 + width="94.285713" 105.113 + height="20.714285" 105.114 + x="138" 105.115 + y="297.76227" /> 105.116 + <text 105.117 + xml:space="preserve" 105.118 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier" 105.119 + x="162.09892" 105.120 + y="311.38342" 105.121 + id="text2824"><tspan 105.122 + sodipodi:role="line" 105.123 + id="tspan2826" 105.124 + x="162.09892" 105.125 + y="311.38342" 105.126 + style="font-family:Courier"><tspan 105.127 + style="font-weight:bold" 105.128 + id="tspan2862">4</tspan>: REV4</tspan></text> 105.129 + <path 105.130 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" 105.131 + d="M 185.14286,343.63731 L 185.14286,319.47656" 105.132 + id="path2900" 105.133 + inkscape:connector-type="polyline" /> 105.134 + <rect 105.135 + style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" 105.136 + id="rect2863" 105.137 + width="94.285713" 105.138 + height="20.714285" 105.139 + x="91.428574" 105.140 + y="250.47656" /> 105.141 + <text 105.142 + xml:space="preserve" 105.143 + style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier" 105.144 + x="116.09886" 105.145 + y="264.56592" 105.146 + id="text1965" 105.147 + transform="scale(1.000002,0.999998)"><tspan 105.148 + sodipodi:role="line" 105.149 + id="tspan1967" 105.150 + x="116.09886" 105.151 + y="264.56592" 105.152 + style="font-family:Courier"><tspan 105.153 + style="font-weight:bold" 105.154 + id="tspan1973">5</tspan>: REV_my_new_hello</tspan></text> 105.155 + <path 105.156 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline" 105.157 + d="M 173.95727,296.76228 L 149.75702,272.19085" 105.158 + id="path1971" 105.159 + inkscape:connector-type="polyline" 105.160 + inkscape:connection-end="#rect2863" 105.161 + inkscape:connection-start="#rect2830" /> 105.162 + <rect 105.163 + style="fill:#78a5ad;fill-opacity:1;stroke:#507b84;stroke-width:2.00000286;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" 105.164 + id="rect2911" 105.165 + width="94.285995" 105.166 + height="20.714283" 105.167 + x="186.71414" 105.168 + y="204.40514" /> 105.169 + <text 105.170 + xml:space="preserve" 105.171 + style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier" 105.172 + x="210.81311" 105.173 + y="218.02673" 105.174 + id="text2913" 105.175 + transform="scale(1.000002,0.999998)"><tspan 105.176 + sodipodi:role="line" 105.177 + id="tspan2915" 105.178 + x="210.81311" 105.179 + y="218.02673" 105.180 + style="font-family:Courier"><tspan 105.181 + id="tspan1966" 105.182 + style="font-weight:bold">6</tspan>: REV6_my_new_hello</tspan></text> 105.183 + <path 105.184 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline" 105.185 + d="M 191.06908,296.76228 L 227.93092,226.11942" 105.186 + id="path2919" 105.187 + inkscape:connector-type="polyline" 105.188 + inkscape:connection-start="#rect2830" /> 105.189 + <text 105.190 + xml:space="preserve" 105.191 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;text-anchor:start;text-align:start;writing-mode:lr;line-height:125%" 105.192 + x="295.28571" 105.193 + y="217.56711" 105.194 + id="text2871" 105.195 + sodipodi:linespacing="125%"><tspan 105.196 + sodipodi:role="line" 105.197 + id="tspan2441">punta (y frente)</tspan></text> 105.198 + <text 105.199 + xml:space="preserve" 105.200 + style="font-size:12px;font-style:normal;font-weight:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 105.201 + x="57.817253" 105.202 + y="263.90753" 105.203 + id="text2875" 105.204 + sodipodi:linespacing="125%"><tspan 105.205 + sodipodi:role="line" 105.206 + id="tspan2439" 105.207 + x="57.817253" 105.208 + y="263.90753">frente</tspan></text> 105.209 + <rect 105.210 + style="fill:#c8aaa5;fill-opacity:1;stroke:#a07163;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:2, 4;stroke-dashoffset:0;stroke-opacity:1" 105.211 + id="rect1913" 105.212 + width="94.285713" 105.213 + height="20.714285" 105.214 + x="138" 105.215 + y="156.90514" /> 105.216 + <path 105.217 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 2;stroke-dashoffset:0;stroke-opacity:1" 105.218 + d="M 144.22399,249.47657 L 179.49029,178.61943" 105.219 + id="path1915" 105.220 + inkscape:connector-type="polyline" 105.221 + inkscape:connection-start="#rect2863" 105.222 + inkscape:connection-end="#rect1913" /> 105.223 + <path 105.224 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 2;stroke-dashoffset:0;stroke-opacity:1" 105.225 + d="M 222.20966,203.40514 L 196.79033,178.61943" 105.226 + id="path1917" 105.227 + inkscape:connector-type="polyline" 105.228 + inkscape:connection-start="#rect2911" 105.229 + inkscape:connection-end="#rect1913" /> 105.230 + <text 105.231 + xml:space="preserve" 105.232 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 105.233 + x="166.16823" 105.234 + y="168.52228" 105.235 + id="text2806"><tspan 105.236 + sodipodi:role="line" 105.237 + id="tspan2808" 105.238 + x="166.16823" 105.239 + y="168.52228" 105.240 + style="font-family:Courier">fusión</tspan></text> 105.241 + <text 105.242 + xml:space="preserve" 105.243 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 105.244 + x="246" 105.245 + y="162.63338" 105.246 + id="text2810"><tspan 105.247 + sodipodi:role="line" 105.248 + x="246" 105.249 + y="162.63338" 105.250 + id="tspan2814">directorio de trabajo</tspan><tspan 105.251 + sodipodi:role="line" 105.252 + x="246" 105.253 + y="177.63338" 105.254 + id="tspan3538">durante la fusión</tspan></text> 105.255 + <rect 105.256 + style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" 105.257 + id="rect2816" 105.258 + width="94.285713" 105.259 + height="20.714285" 105.260 + x="483.14636" 105.261 + y="297.76227" /> 105.262 + <text 105.263 + xml:space="preserve" 105.264 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier" 105.265 + x="507.24527" 105.266 + y="311.38342" 105.267 + id="text2818"><tspan 105.268 + sodipodi:role="line" 105.269 + id="tspan2820" 105.270 + x="507.24527" 105.271 + y="311.38342" 105.272 + style="font-family:Courier"><tspan 105.273 + style="font-weight:bold" 105.274 + id="tspan2822">4</tspan>: REV4</tspan></text> 105.275 + <path 105.276 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" 105.277 + d="M 530.28921,343.6373 L 530.28921,319.47655" 105.278 + id="path2824" 105.279 + inkscape:connector-type="polyline" /> 105.280 + <rect 105.281 + style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" 105.282 + id="rect2826" 105.283 + width="94.285713" 105.284 + height="20.714285" 105.285 + x="436.57492" 105.286 + y="250.47656" /> 105.287 + <text 105.288 + xml:space="preserve" 105.289 + style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier" 105.290 + x="461.24484" 105.291 + y="264.56613" 105.292 + id="text2828" 105.293 + transform="scale(1.000002,0.999998)"><tspan 105.294 + sodipodi:role="line" 105.295 + id="tspan2830" 105.296 + x="461.24484" 105.297 + y="264.56613" 105.298 + style="font-family:Courier"><tspan 105.299 + style="font-weight:bold" 105.300 + id="tspan2832">5</tspan>: REV_my_new_hello</tspan></text> 105.301 + <path 105.302 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline" 105.303 + d="M 519.10362,296.76227 L 494.90337,272.19084" 105.304 + id="path2834" 105.305 + inkscape:connector-type="polyline" /> 105.306 + <rect 105.307 + style="fill:#78a5ad;fill-opacity:1;stroke:#507b84;stroke-width:2.00000286;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" 105.308 + id="rect2836" 105.309 + width="94.285995" 105.310 + height="20.714283" 105.311 + x="483.14001" 105.312 + y="156.548" /> 105.313 + <text 105.314 + xml:space="preserve" 105.315 + style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier" 105.316 + x="555.95911" 105.317 + y="218.02698" 105.318 + id="text2838" 105.319 + transform="scale(1.000002,0.999998)"><tspan 105.320 + sodipodi:role="line" 105.321 + id="tspan2840" 105.322 + x="555.95911" 105.323 + y="218.02698" 105.324 + style="font-family:Courier"><tspan 105.325 + id="tspan2842" 105.326 + style="font-weight:bold">6</tspan>: REV6_my_new_hello</tspan></text> 105.327 + <path 105.328 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline" 105.329 + d="M 536.21543,296.76227 L 574.03453,224.76218" 105.330 + id="path2844" 105.331 + inkscape:connector-type="polyline" /> 105.332 + <text 105.333 + xml:space="preserve" 105.334 + style="font-size:12px;font-style:normal;font-weight:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 105.335 + x="452.00058" 105.336 + y="167.76765" 105.337 + id="text2846" 105.338 + sodipodi:linespacing="125%"><tspan 105.339 + sodipodi:role="line" 105.340 + id="tspan2443" 105.341 + x="452.00058" 105.342 + y="167.76765">punta</tspan></text> 105.343 + <path 105.344 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-start:none;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" 105.345 + d="M 489.37034,249.47656 L 524.65575,178.26229" 105.346 + id="path2856" 105.347 + inkscape:connector-type="polyline" 105.348 + inkscape:connection-end="#rect2836" /> 105.349 + <path 105.350 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" 105.351 + d="M 567.85714,202.0479 L 542.42591,178.26229" 105.352 + id="path2858" 105.353 + inkscape:connector-type="polyline" 105.354 + inkscape:connection-end="#rect2836" 105.355 + inkscape:connection-start="#rect2995" /> 105.356 + <text 105.357 + xml:space="preserve" 105.358 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 105.359 + x="490.40295" 105.360 + y="170.39714" 105.361 + id="text2860"><tspan 105.362 + sodipodi:role="line" 105.363 + id="tspan2863" 105.364 + x="490.40295" 105.365 + y="170.39714" 105.366 + style="font-family:Courier"><tspan 105.367 + style="font-weight:bold" 105.368 + id="tspan2997">7</tspan>: REV7_my_new_hello</tspan></text> 105.369 + <text 105.370 + xml:space="preserve" 105.371 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 105.372 + x="90.323105" 105.373 + y="120.21933" 105.374 + id="text2929"><tspan 105.375 + sodipodi:role="line" 105.376 + id="tspan2931" 105.377 + x="90.323105" 105.378 + y="120.21933" 105.379 + style="font-weight:bold">Directorio de trabajo durante la fusión</tspan></text> 105.380 + <text 105.381 + xml:space="preserve" 105.382 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 105.383 + x="435.35226" 105.384 + y="120.21933" 105.385 + id="text2937"><tspan 105.386 + sodipodi:role="line" 105.387 + id="tspan2939" 105.388 + x="435.35226" 105.389 + y="120.21933" 105.390 + style="font-weight:bold">Repositorio después de consignar la fusión</tspan></text> 105.391 + </g> 105.392 +</svg>
106.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 106.2 +++ b/es/tour-merge-pull.svg Thu Jan 29 22:00:07 2009 -0800 106.3 @@ -0,0 +1,297 @@ 106.4 +<?xml version="1.0" encoding="UTF-8" standalone="no"?> 106.5 +<!-- Created with Inkscape (http://www.inkscape.org/) --> 106.6 +<svg 106.7 + xmlns:dc="http://purl.org/dc/elements/1.1/" 106.8 + xmlns:cc="http://creativecommons.org/ns#" 106.9 + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 106.10 + xmlns:svg="http://www.w3.org/2000/svg" 106.11 + xmlns="http://www.w3.org/2000/svg" 106.12 + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" 106.13 + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" 106.14 + width="744.09448819" 106.15 + height="1052.3622047" 106.16 + id="svg2" 106.17 + sodipodi:version="0.32" 106.18 + inkscape:version="0.46" 106.19 + sodipodi:docname="tour-merge-pull.svg" 106.20 + sodipodi:docbase="/home/bos/hg/hgbook/en" 106.21 + inkscape:output_extension="org.inkscape.output.svg.inkscape"> 106.22 + <defs 106.23 + id="defs4"> 106.24 + <inkscape:perspective 106.25 + sodipodi:type="inkscape:persp3d" 106.26 + inkscape:vp_x="0 : 526.18109 : 1" 106.27 + inkscape:vp_y="0 : 1000 : 0" 106.28 + inkscape:vp_z="744.09448 : 526.18109 : 1" 106.29 + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" 106.30 + id="perspective2979" /> 106.31 + <marker 106.32 + inkscape:stockid="Arrow1Mstart" 106.33 + orient="auto" 106.34 + refY="0.0" 106.35 + refX="0.0" 106.36 + id="Arrow1Mstart" 106.37 + style="overflow:visible"> 106.38 + <path 106.39 + id="path2973" 106.40 + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " 106.41 + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none" 106.42 + transform="scale(0.4) translate(10,0)" /> 106.43 + </marker> 106.44 + <marker 106.45 + inkscape:stockid="Arrow1Mend" 106.46 + orient="auto" 106.47 + refY="0.0" 106.48 + refX="0.0" 106.49 + id="Arrow1Mend" 106.50 + style="overflow:visible;"> 106.51 + <path 106.52 + id="path3066" 106.53 + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " 106.54 + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;" 106.55 + transform="scale(0.4) rotate(180) translate(10,0)" /> 106.56 + </marker> 106.57 + </defs> 106.58 + <sodipodi:namedview 106.59 + id="base" 106.60 + pagecolor="#ffffff" 106.61 + bordercolor="#666666" 106.62 + borderopacity="1.0" 106.63 + gridtolerance="10000" 106.64 + guidetolerance="10" 106.65 + objecttolerance="10" 106.66 + inkscape:pageopacity="0.0" 106.67 + inkscape:pageshadow="2" 106.68 + inkscape:zoom="1.4" 106.69 + inkscape:cx="233.63208" 106.70 + inkscape:cy="704.83702" 106.71 + inkscape:document-units="px" 106.72 + inkscape:current-layer="layer1" 106.73 + inkscape:window-width="906" 106.74 + inkscape:window-height="659" 106.75 + inkscape:window-x="237" 106.76 + inkscape:window-y="103" 106.77 + showgrid="false" /> 106.78 + <metadata 106.79 + id="metadata7"> 106.80 + <rdf:RDF> 106.81 + <cc:Work 106.82 + rdf:about=""> 106.83 + <dc:format>image/svg+xml</dc:format> 106.84 + <dc:type 106.85 + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> 106.86 + </cc:Work> 106.87 + </rdf:RDF> 106.88 + </metadata> 106.89 + <g 106.90 + inkscape:label="Layer 1" 106.91 + inkscape:groupmode="layer" 106.92 + id="layer1"> 106.93 + <text 106.94 + xml:space="preserve" 106.95 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier" 106.96 + x="173.57143" 106.97 + y="443.79074" 106.98 + id="text2832"><tspan 106.99 + sodipodi:role="line" 106.100 + id="tspan2834" 106.101 + x="173.57143" 106.102 + y="443.79074" /></text> 106.103 + <rect 106.104 + style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" 106.105 + id="rect1878" 106.106 + width="94.285713" 106.107 + height="20.714285" 106.108 + x="138" 106.109 + y="479.50504" /> 106.110 + <text 106.111 + xml:space="preserve" 106.112 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier" 106.113 + x="162.09892" 106.114 + y="493.12619" 106.115 + id="text1872"><tspan 106.116 + sodipodi:role="line" 106.117 + id="tspan1874" 106.118 + x="162.09892" 106.119 + y="493.12619" 106.120 + style="font-family:Courier"><tspan 106.121 + style="font-weight:bold" 106.122 + id="tspan1876">0</tspan>: REV0</tspan></text> 106.123 + <rect 106.124 + style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" 106.125 + id="rect2800" 106.126 + width="94.285713" 106.127 + height="20.714285" 106.128 + x="138" 106.129 + y="432.63004" /> 106.130 + <text 106.131 + xml:space="preserve" 106.132 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier" 106.133 + x="162.09892" 106.134 + y="446.25119" 106.135 + id="text2794"><tspan 106.136 + sodipodi:role="line" 106.137 + id="tspan2796" 106.138 + x="162.09892" 106.139 + y="446.25119" 106.140 + style="font-family:Courier"><tspan 106.141 + id="tspan2868" 106.142 + style="font-weight:bold">1</tspan>: REV1</tspan></text> 106.143 + <rect 106.144 + style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" 106.145 + id="rect2810" 106.146 + width="94.285713" 106.147 + height="20.714285" 106.148 + x="138" 106.149 + y="385.75504" /> 106.150 + <text 106.151 + xml:space="preserve" 106.152 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier" 106.153 + x="162.09892" 106.154 + y="399.37619" 106.155 + id="text2804"><tspan 106.156 + sodipodi:role="line" 106.157 + id="tspan2806" 106.158 + x="162.09892" 106.159 + y="399.37619" 106.160 + style="font-family:Courier"><tspan 106.161 + style="font-weight:bold" 106.162 + id="tspan2866">2</tspan>: REV2</tspan></text> 106.163 + <rect 106.164 + style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" 106.165 + id="rect2820" 106.166 + width="94.285713" 106.167 + height="20.714285" 106.168 + x="138" 106.169 + y="338.88007" /> 106.170 + <text 106.171 + xml:space="preserve" 106.172 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier" 106.173 + x="162.09892" 106.174 + y="352.50122" 106.175 + id="text2814"><tspan 106.176 + sodipodi:role="line" 106.177 + id="tspan2816" 106.178 + x="162.09892" 106.179 + y="352.50122" 106.180 + style="font-family:Courier"><tspan 106.181 + style="font-weight:bold" 106.182 + id="tspan2864">3</tspan>: REV3</tspan></text> 106.183 + <rect 106.184 + style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" 106.185 + id="rect2830" 106.186 + width="94.285713" 106.187 + height="20.714285" 106.188 + x="138" 106.189 + y="292.00504" /> 106.190 + <text 106.191 + xml:space="preserve" 106.192 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier" 106.193 + x="162.09892" 106.194 + y="305.62619" 106.195 + id="text2824"><tspan 106.196 + sodipodi:role="line" 106.197 + id="tspan2826" 106.198 + x="162.09892" 106.199 + y="305.62619" 106.200 + style="font-family:Courier"><tspan 106.201 + style="font-weight:bold" 106.202 + id="tspan2862">4</tspan>: REV4</tspan></text> 106.203 + <path 106.204 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" 106.205 + d="M 185.14286,478.50504 L 185.14286,454.34432" 106.206 + id="path2894" 106.207 + inkscape:connector-type="polyline" /> 106.208 + <path 106.209 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" 106.210 + d="M 185.14286,431.63004 L 185.14286,407.46932" 106.211 + id="path2896" 106.212 + inkscape:connector-type="polyline" /> 106.213 + <path 106.214 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" 106.215 + d="M 185.14286,384.75504 L 185.14286,360.59435" 106.216 + id="path2898" 106.217 + inkscape:connector-type="polyline" /> 106.218 + <path 106.219 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" 106.220 + d="M 185.14286,337.88007 L 185.14286,313.71932" 106.221 + id="path2900" 106.222 + inkscape:connector-type="polyline" /> 106.223 + <rect 106.224 + style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" 106.225 + id="rect2863" 106.226 + width="94.285713" 106.227 + height="20.714285" 106.228 + x="91.428574" 106.229 + y="244.71933" /> 106.230 + <text 106.231 + xml:space="preserve" 106.232 + style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier" 106.233 + x="116.09886" 106.234 + y="258.80865" 106.235 + id="text1965" 106.236 + transform="scale(1.000002,0.999998)"><tspan 106.237 + sodipodi:role="line" 106.238 + id="tspan1967" 106.239 + x="116.09886" 106.240 + y="258.80865" 106.241 + style="font-family:Courier"><tspan 106.242 + style="font-weight:bold" 106.243 + id="tspan1973">5</tspan>: REV_my_new_hello</tspan></text> 106.244 + <path 106.245 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline" 106.246 + d="M 173.95727,291.00504 L 149.75702,266.43361" 106.247 + id="path1971" 106.248 + inkscape:connector-type="polyline" 106.249 + inkscape:connection-end="#rect2863" 106.250 + inkscape:connection-start="#rect2830" /> 106.251 + <rect 106.252 + style="fill:#78a5ad;fill-opacity:1;stroke:#507b84;stroke-width:2.00000286;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" 106.253 + id="rect2911" 106.254 + width="94.285995" 106.255 + height="20.714283" 106.256 + x="186.71414" 106.257 + y="198.6479" /> 106.258 + <text 106.259 + xml:space="preserve" 106.260 + style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier" 106.261 + x="210.81311" 106.262 + y="212.26949" 106.263 + id="text2913" 106.264 + transform="scale(1.000002,0.999998)"><tspan 106.265 + sodipodi:role="line" 106.266 + id="tspan2915" 106.267 + x="210.81311" 106.268 + y="212.26949" 106.269 + style="font-family:Courier"><tspan 106.270 + id="tspan1966" 106.271 + style="font-weight:bold">6</tspan>: REV6_my_new_hello</tspan></text> 106.272 + <path 106.273 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline" 106.274 + d="M 191.06908,291.00504 L 227.93092,220.36218" 106.275 + id="path2919" 106.276 + inkscape:connector-type="polyline" 106.277 + inkscape:connection-start="#rect2830" /> 106.278 + <text 106.279 + xml:space="preserve" 106.280 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 106.281 + x="291" 106.282 + y="225.3813" 106.283 + id="text2871"><tspan 106.284 + sodipodi:role="line" 106.285 + id="tspan2873" 106.286 + x="291" 106.287 + y="225.3813">tip (y principal)</tspan></text> 106.288 + <text 106.289 + xml:space="preserve" 106.290 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 106.291 + x="76" 106.292 + y="259.16046" 106.293 + id="text2875"><tspan 106.294 + sodipodi:role="line" 106.295 + id="tspan2877" 106.296 + x="76" 106.297 + y="259.16046" 106.298 + style="text-align:end;text-anchor:end">principal</tspan></text> 106.299 + </g> 106.300 +</svg>
107.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 107.2 +++ b/es/tour-merge-sep-repos.svg Thu Jan 29 22:00:07 2009 -0800 107.3 @@ -0,0 +1,480 @@ 107.4 +<?xml version="1.0" encoding="UTF-8" standalone="no"?> 107.5 +<!-- Created with Inkscape (http://www.inkscape.org/) --> 107.6 +<svg 107.7 + xmlns:dc="http://purl.org/dc/elements/1.1/" 107.8 + xmlns:cc="http://creativecommons.org/ns#" 107.9 + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 107.10 + xmlns:svg="http://www.w3.org/2000/svg" 107.11 + xmlns="http://www.w3.org/2000/svg" 107.12 + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" 107.13 + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" 107.14 + width="744.09448819" 107.15 + height="1052.3622047" 107.16 + id="svg2" 107.17 + sodipodi:version="0.32" 107.18 + inkscape:version="0.46" 107.19 + sodipodi:docname="tour-merge-sep-repos.svg" 107.20 + inkscape:output_extension="org.inkscape.output.svg.inkscape"> 107.21 + <defs 107.22 + id="defs4"> 107.23 + <inkscape:perspective 107.24 + sodipodi:type="inkscape:persp3d" 107.25 + inkscape:vp_x="0 : 526.18109 : 1" 107.26 + inkscape:vp_y="0 : 1000 : 0" 107.27 + inkscape:vp_z="744.09448 : 526.18109 : 1" 107.28 + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" 107.29 + id="perspective3067" /> 107.30 + <marker 107.31 + inkscape:stockid="Arrow1Mstart" 107.32 + orient="auto" 107.33 + refY="0.0" 107.34 + refX="0.0" 107.35 + id="Arrow1Mstart" 107.36 + style="overflow:visible"> 107.37 + <path 107.38 + id="path2973" 107.39 + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " 107.40 + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none" 107.41 + transform="scale(0.4) translate(10,0)" /> 107.42 + </marker> 107.43 + <marker 107.44 + inkscape:stockid="Arrow1Mend" 107.45 + orient="auto" 107.46 + refY="0.0" 107.47 + refX="0.0" 107.48 + id="Arrow1Mend" 107.49 + style="overflow:visible;"> 107.50 + <path 107.51 + id="path3066" 107.52 + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " 107.53 + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;" 107.54 + transform="scale(0.4) rotate(180) translate(10,0)" /> 107.55 + </marker> 107.56 + </defs> 107.57 + <sodipodi:namedview 107.58 + id="base" 107.59 + pagecolor="#ffffff" 107.60 + bordercolor="#666666" 107.61 + borderopacity="1.0" 107.62 + gridtolerance="10000" 107.63 + guidetolerance="10" 107.64 + objecttolerance="10" 107.65 + inkscape:pageopacity="0.0" 107.66 + inkscape:pageshadow="2" 107.67 + inkscape:zoom="1.4" 107.68 + inkscape:cx="307.20351" 107.69 + inkscape:cy="683.39831" 107.70 + inkscape:document-units="px" 107.71 + inkscape:current-layer="layer1" 107.72 + inkscape:window-width="906" 107.73 + inkscape:window-height="659" 107.74 + inkscape:window-x="5" 107.75 + inkscape:window-y="49" 107.76 + showgrid="false" /> 107.77 + <metadata 107.78 + id="metadata7"> 107.79 + <rdf:RDF> 107.80 + <cc:Work 107.81 + rdf:about=""> 107.82 + <dc:format>image/svg+xml</dc:format> 107.83 + <dc:type 107.84 + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> 107.85 + </cc:Work> 107.86 + </rdf:RDF> 107.87 + </metadata> 107.88 + <g 107.89 + inkscape:label="Layer 1" 107.90 + inkscape:groupmode="layer" 107.91 + id="layer1"> 107.92 + <text 107.93 + xml:space="preserve" 107.94 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier" 107.95 + x="173.57143" 107.96 + y="443.79074" 107.97 + id="text2832"><tspan 107.98 + sodipodi:role="line" 107.99 + id="tspan2834" 107.100 + x="173.57143" 107.101 + y="443.79074" /></text> 107.102 + <rect 107.103 + style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" 107.104 + id="rect1878" 107.105 + width="94.285713" 107.106 + height="20.714285" 107.107 + x="138" 107.108 + y="479.50504" /> 107.109 + <text 107.110 + xml:space="preserve" 107.111 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier" 107.112 + x="162.09892" 107.113 + y="493.12619" 107.114 + id="text1872"><tspan 107.115 + sodipodi:role="line" 107.116 + id="tspan1874" 107.117 + x="162.09892" 107.118 + y="493.12619" 107.119 + style="font-family:Courier"><tspan 107.120 + style="font-weight:bold" 107.121 + id="tspan1876">0</tspan>: REV0</tspan></text> 107.122 + <rect 107.123 + style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" 107.124 + id="rect2800" 107.125 + width="94.285713" 107.126 + height="20.714285" 107.127 + x="138" 107.128 + y="432.63004" /> 107.129 + <text 107.130 + xml:space="preserve" 107.131 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier" 107.132 + x="162.09892" 107.133 + y="446.25119" 107.134 + id="text2794"><tspan 107.135 + sodipodi:role="line" 107.136 + id="tspan2796" 107.137 + x="162.09892" 107.138 + y="446.25119" 107.139 + style="font-family:Courier"><tspan 107.140 + id="tspan2868" 107.141 + style="font-weight:bold">1</tspan>: REV1</tspan></text> 107.142 + <rect 107.143 + style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" 107.144 + id="rect2810" 107.145 + width="94.285713" 107.146 + height="20.714285" 107.147 + x="138" 107.148 + y="385.75504" /> 107.149 + <text 107.150 + xml:space="preserve" 107.151 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier" 107.152 + x="162.09892" 107.153 + y="399.37619" 107.154 + id="text2804"><tspan 107.155 + sodipodi:role="line" 107.156 + id="tspan2806" 107.157 + x="162.09892" 107.158 + y="399.37619" 107.159 + style="font-family:Courier"><tspan 107.160 + style="font-weight:bold" 107.161 + id="tspan2866">2</tspan>: REV2</tspan></text> 107.162 + <rect 107.163 + style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" 107.164 + id="rect2820" 107.165 + width="94.285713" 107.166 + height="20.714285" 107.167 + x="138" 107.168 + y="338.88007" /> 107.169 + <text 107.170 + xml:space="preserve" 107.171 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier" 107.172 + x="162.09892" 107.173 + y="352.50122" 107.174 + id="text2814"><tspan 107.175 + sodipodi:role="line" 107.176 + id="tspan2816" 107.177 + x="162.09892" 107.178 + y="352.50122" 107.179 + style="font-family:Courier"><tspan 107.180 + style="font-weight:bold" 107.181 + id="tspan2864">3</tspan>: REV3</tspan></text> 107.182 + <rect 107.183 + style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" 107.184 + id="rect2830" 107.185 + width="94.285713" 107.186 + height="20.714285" 107.187 + x="138" 107.188 + y="292.00504" /> 107.189 + <text 107.190 + xml:space="preserve" 107.191 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier" 107.192 + x="162.09892" 107.193 + y="305.62619" 107.194 + id="text2824"><tspan 107.195 + sodipodi:role="line" 107.196 + id="tspan2826" 107.197 + x="162.09892" 107.198 + y="305.62619" 107.199 + style="font-family:Courier"><tspan 107.200 + style="font-weight:bold" 107.201 + id="tspan2862">4</tspan>: REV4</tspan></text> 107.202 + <path 107.203 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" 107.204 + d="M 185.14286,478.50504 L 185.14286,454.34432" 107.205 + id="path2894" 107.206 + inkscape:connector-type="polyline" /> 107.207 + <path 107.208 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" 107.209 + d="M 185.14286,431.63004 L 185.14286,407.46932" 107.210 + id="path2896" 107.211 + inkscape:connector-type="polyline" /> 107.212 + <path 107.213 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" 107.214 + d="M 185.14286,384.75504 L 185.14286,360.59435" 107.215 + id="path2898" 107.216 + inkscape:connector-type="polyline" /> 107.217 + <path 107.218 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" 107.219 + d="M 185.14286,337.88007 L 185.14286,313.71932" 107.220 + id="path2900" 107.221 + inkscape:connector-type="polyline" /> 107.222 + <rect 107.223 + style="fill:#78a5ad;fill-opacity:1;stroke:#507b84;stroke-width:2.00000286;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" 107.224 + id="rect1963" 107.225 + width="94.285995" 107.226 + height="20.714283" 107.227 + x="138" 107.228 + y="245.18723" /> 107.229 + <text 107.230 + xml:space="preserve" 107.231 + style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier" 107.232 + x="162.09877" 107.233 + y="258.80865" 107.234 + id="text1965" 107.235 + transform="scale(1.000002,0.999998)"><tspan 107.236 + sodipodi:role="line" 107.237 + id="tspan1967" 107.238 + x="162.09877" 107.239 + y="258.80865" 107.240 + style="font-family:Courier"><tspan 107.241 + style="font-weight:bold" 107.242 + id="tspan1973">5</tspan>: REV_my_hello</tspan></text> 107.243 + <path 107.244 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" 107.245 + d="M 185.143,291.06218 L 185.143,266.90143" 107.246 + id="path1971" 107.247 + inkscape:connector-type="polyline" /> 107.248 + <text 107.249 + xml:space="preserve" 107.250 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 107.251 + x="136.90039" 107.252 + y="232.25546" 107.253 + id="text2921"><tspan 107.254 + sodipodi:role="line" 107.255 + id="tspan2923" 107.256 + x="136.90039" 107.257 + y="232.25546">my-hello</tspan></text> 107.258 + <rect 107.259 + style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" 107.260 + id="rect2863" 107.261 + width="94.285713" 107.262 + height="20.714285" 107.263 + x="370.71414" 107.264 + y="479.49289" /> 107.265 + <text 107.266 + xml:space="preserve" 107.267 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier" 107.268 + x="394.81305" 107.269 + y="493.11404" 107.270 + id="text2865"><tspan 107.271 + sodipodi:role="line" 107.272 + id="tspan2867" 107.273 + x="394.81305" 107.274 + y="493.11404" 107.275 + style="font-family:Courier"><tspan 107.276 + style="font-weight:bold" 107.277 + id="tspan2869">0</tspan>: REV0</tspan></text> 107.278 + <rect 107.279 + style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" 107.280 + id="rect2871" 107.281 + width="94.285713" 107.282 + height="20.714285" 107.283 + x="370.71414" 107.284 + y="432.61789" /> 107.285 + <text 107.286 + xml:space="preserve" 107.287 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier" 107.288 + x="394.81305" 107.289 + y="446.23904" 107.290 + id="text2873"><tspan 107.291 + sodipodi:role="line" 107.292 + id="tspan2875" 107.293 + x="394.81305" 107.294 + y="446.23904" 107.295 + style="font-family:Courier"><tspan 107.296 + id="tspan2877" 107.297 + style="font-weight:bold">1</tspan>: REV1</tspan></text> 107.298 + <rect 107.299 + style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" 107.300 + id="rect2879" 107.301 + width="94.285713" 107.302 + height="20.714285" 107.303 + x="370.71414" 107.304 + y="385.74289" /> 107.305 + <text 107.306 + xml:space="preserve" 107.307 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier" 107.308 + x="394.81305" 107.309 + y="399.36404" 107.310 + id="text2881"><tspan 107.311 + sodipodi:role="line" 107.312 + id="tspan2883" 107.313 + x="394.81305" 107.314 + y="399.36404" 107.315 + style="font-family:Courier"><tspan 107.316 + style="font-weight:bold" 107.317 + id="tspan2885">2</tspan>: REV2</tspan></text> 107.318 + <rect 107.319 + style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" 107.320 + id="rect2887" 107.321 + width="94.285713" 107.322 + height="20.714285" 107.323 + x="370.71414" 107.324 + y="338.86792" /> 107.325 + <text 107.326 + xml:space="preserve" 107.327 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier" 107.328 + x="394.81305" 107.329 + y="352.48907" 107.330 + id="text2889"><tspan 107.331 + sodipodi:role="line" 107.332 + id="tspan2891" 107.333 + x="394.81305" 107.334 + y="352.48907" 107.335 + style="font-family:Courier"><tspan 107.336 + style="font-weight:bold" 107.337 + id="tspan2893">3</tspan>: REV3</tspan></text> 107.338 + <rect 107.339 + style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" 107.340 + id="rect2895" 107.341 + width="94.285713" 107.342 + height="20.714285" 107.343 + x="370.71414" 107.344 + y="291.99289" /> 107.345 + <text 107.346 + xml:space="preserve" 107.347 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier" 107.348 + x="394.81305" 107.349 + y="305.61404" 107.350 + id="text2897"><tspan 107.351 + sodipodi:role="line" 107.352 + id="tspan2899" 107.353 + x="394.81305" 107.354 + y="305.61404" 107.355 + style="font-family:Courier"><tspan 107.356 + style="font-weight:bold" 107.357 + id="tspan2901">4</tspan>: REV4</tspan></text> 107.358 + <path 107.359 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" 107.360 + d="M 417.85701,478.4929 L 417.85701,454.33218" 107.361 + id="path2903" 107.362 + inkscape:connector-type="polyline" /> 107.363 + <path 107.364 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" 107.365 + d="M 417.85701,431.6179 L 417.85701,407.45718" 107.366 + id="path2905" 107.367 + inkscape:connector-type="polyline" /> 107.368 + <path 107.369 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" 107.370 + d="M 417.85701,384.7429 L 417.85701,360.58221" 107.371 + id="path2907" 107.372 + inkscape:connector-type="polyline" /> 107.373 + <path 107.374 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" 107.375 + d="M 417.85701,337.86793 L 417.85701,313.70718" 107.376 + id="path2909" 107.377 + inkscape:connector-type="polyline" /> 107.378 + <rect 107.379 + style="fill:#78a5ad;fill-opacity:1;stroke:#507b84;stroke-width:2.00000286;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" 107.380 + id="rect2911" 107.381 + width="94.285995" 107.382 + height="20.714283" 107.383 + x="370.71414" 107.384 + y="245.17511" /> 107.385 + <text 107.386 + xml:space="preserve" 107.387 + style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier" 107.388 + x="394.81274" 107.389 + y="258.79678" 107.390 + id="text2913" 107.391 + transform="scale(1.000002,0.999998)"><tspan 107.392 + sodipodi:role="line" 107.393 + id="tspan2915" 107.394 + x="394.81274" 107.395 + y="258.79678" 107.396 + style="font-family:Courier"><tspan 107.397 + style="font-weight:bold" 107.398 + id="tspan2917">5</tspan>: REV_my_new_hello</tspan></text> 107.399 + <path 107.400 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" 107.401 + d="M 417.85715,291.05004 L 417.85715,266.88929" 107.402 + id="path2919" 107.403 + inkscape:connector-type="polyline" /> 107.404 + <text 107.405 + xml:space="preserve" 107.406 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 107.407 + x="369.61453" 107.408 + y="232.25546" 107.409 + id="text2925"><tspan 107.410 + sodipodi:role="line" 107.411 + id="tspan2927" 107.412 + x="369.61453" 107.413 + y="232.25546">my-new-hello</tspan></text> 107.414 + <text 107.415 + xml:space="preserve" 107.416 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 107.417 + x="300.54352" 107.418 + y="252.12723" 107.419 + id="text2933"><tspan 107.420 + sodipodi:role="line" 107.421 + id="tspan2935" 107.422 + x="300.54352" 107.423 + y="252.12723" 107.424 + style="text-align:center;text-anchor:middle">Los cambios</tspan><tspan 107.425 + sodipodi:role="line" 107.426 + x="300.54352" 107.427 + y="267.12723" 107.428 + style="text-align:center;text-anchor:middle" 107.429 + id="tspan3494">más recientes</tspan><tspan 107.430 + sodipodi:role="line" 107.431 + x="300.54352" 107.432 + y="282.12723" 107.433 + style="text-align:center;text-anchor:middle" 107.434 + id="tspan3132">difieren</tspan></text> 107.435 + <text 107.436 + xml:space="preserve" 107.437 + style="font-size:12px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 107.438 + x="262.15436" 107.439 + y="398.37112" 107.440 + id="text2929"><tspan 107.441 + sodipodi:role="line" 107.442 + x="262.15436" 107.443 + y="398.37112" 107.444 + id="tspan3013" 107.445 + style="text-align:start;text-anchor:start">historia común</tspan></text> 107.446 + <g 107.447 + id="g3107" 107.448 + transform="translate(0,0.855744)"> 107.449 + <path 107.450 + id="path3101" 107.451 + d="M 300.35713,381.29075 L 300.35713,304.50504" 107.452 + style="fill:black;fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4, 4;stroke-dashoffset:0;stroke-opacity:1" /> 107.453 + <path 107.454 + id="path3105" 107.455 + d="M 291.07142,301.64789 L 309.28571,301.64789" 107.456 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#bfbfbf;stroke-width:0.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> 107.457 + </g> 107.458 + <path 107.459 + style="fill:black;fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4, 4;stroke-dashoffset:0;stroke-opacity:1" 107.460 + d="M 300.53571,486.38926 L 300.53571,409.60355" 107.461 + id="path3113" /> 107.462 + <path 107.463 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#bfbfbf;stroke-width:0.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" 107.464 + d="M 291.25,488.49641 L 309.46429,488.49641" 107.465 + id="path3115" /> 107.466 + <text 107.467 + xml:space="preserve" 107.468 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 107.469 + x="480.71429" 107.470 + y="250.91507" 107.471 + id="text1949"><tspan 107.472 + sodipodi:role="line" 107.473 + id="tspan1951" 107.474 + x="480.71429" 107.475 + y="250.91507" 107.476 + style="text-align:start;text-anchor:start">revisión principal</tspan><tspan 107.477 + sodipodi:role="line" 107.478 + x="480.71429" 107.479 + y="265.91507" 107.480 + id="tspan1953" 107.481 + style="text-align:start;text-anchor:start"> (sin hijos)</tspan></text> 107.482 + </g> 107.483 +</svg>
108.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 108.2 +++ b/es/tour-merge.tex Thu Jan 29 22:00:07 2009 -0800 108.3 @@ -0,0 +1,308 @@ 108.4 +\chapter{Una gira de Mercurial: fusionar trabajo} 108.5 +\label{chap:tour-merge} 108.6 + 108.7 +Hasta ahora hemos cubierto cómo clonar un repositorio, hacer cambios, 108.8 +y jalar o empujar dichos cambios de un repositorio a otro. Nuestro 108.9 +siguiente paso es \emph{fusionar} cambios de repositorios separados. 108.10 + 108.11 +% TODO cambié streams por líneas. check please 108.12 +\section{Fusionar líneas de trabajo} 108.13 + 108.14 +Fusionar es una parte fundamental de trabajar con una herramienta 108.15 +de control distribuido de versiones. 108.16 +\begin{itemize} 108.17 +\item Alicia y Roberto tienen cada uno una copia personal del 108.18 + repositorio de un proyecto en el que están trabajando. Alicia 108.19 + arregla un fallo en su repositorio; Roberto añade una nueva 108.20 + característica en el suyo. Ambos desean que el repositorio 108.21 + compartido contenga el arreglo del fallo y la nueva 108.22 + característica. 108.23 +\item Frecuentemente trabajo en varias tareas diferentes en un mismo 108.24 + proyecto al mismo tiempo, cada una aislada convenientemente de las 108.25 + otras en su propio repositorio. Trabajar de esta manera significa 108.26 + que a menudo debo fusionar una parte de mi propio trabajo con 108.27 + otra. 108.28 +\end{itemize} 108.29 + 108.30 +Como fusionar es una operación tan necesaria y común, Mercurial la 108.31 +facilita. Revisemos el proceso. Empezaremos clonando (otro) 108.32 +% TODO poner interrogante de apertura 108.33 +repositorio (ve lo seguido que aparecen?) y haciendo un cambio en él. 108.34 +\interaction{tour.merge.clone} 108.35 +Ahora deberíamos tener dos copias de \filename{hello.c} con contenidos 108.36 +diferentes. El historial de los dos repositorios diverge ahora, como 108.37 +se ilustra en la figura~\ref{fig:tour-merge:sep-repos}. 108.38 +\interaction{tour.merge.cat} 108.39 + 108.40 +\begin{figure}[ht] 108.41 + \centering 108.42 + \grafix{tour-merge-sep-repos} 108.43 + \caption{Historial reciente divergente de los repositorios 108.44 + \dirname{my-hello} y \dirname{my-new-hello}} 108.45 + \label{fig:tour-merge:sep-repos} 108.46 +\end{figure} 108.47 + 108.48 +Ya sabemos que jalar los cambios desde nuestro repositorio 108.49 +\dirname{my-hello} no tendrá efecto en el directorio de trabajo. 108.50 +\interaction{tour.merge.pull} 108.51 +Sin embargo, el comando \hgcmd{pull} dice algo acerca de 108.52 +``frentes''\ndt{El autor se refiere a \emph{heads} aquí.}. 108.53 + 108.54 +\subsection{Conjuntos de cambios de frentes} 108.55 + 108.56 +Un frente es un cambio que no tiene descendientes, o hijos, como 108.57 +también se les conoce. La revisión de punta es, por tanto, un frente, 108.58 +porque la revisión más reciente en un repositorio no tiene ningún 108.59 +% TODO cambio en la redacción de la frase, pero espero que conserve el 108.60 +% sentido. Querido human@, apruebe o corrija :D 108.61 +hijo. Sin embargo, un repositorio puede contener más de un frente. 108.62 + 108.63 +\begin{figure}[ht] 108.64 + \centering 108.65 + \grafix{tour-merge-pull} 108.66 + \caption{Contenidos del repositorio después de jalar 108.67 + \dirname{my-hello} a \dirname{my-new-hello}} 108.68 + \label{fig:tour-merge:pull} 108.69 +\end{figure} 108.70 + 108.71 +En la figura~\ref{fig:tour-merge:pull} usted puede ver el efecto que 108.72 +tiene jalar los cambios de \dirname{my-hello} a \dirname{my-new-hello}. 108.73 +El historial que ya existía en \dirname{my-new-hello} se mantiene 108.74 +intacto, pero fue añadida una nueva revisión. Refiriéndonos a la 108.75 +figura~\ref{fig:tour-merge:sep-repos}, podemos ver que el \emph{ID del 108.76 +conjunto de cambios} se mantiene igual en el nuevo repositorio, pero 108.77 +el \emph{número de revisión} ha cambiado. (Incidentalmente, éste es un 108.78 +buen ejemplo de porqué no es seguro usar números de revisión cuando se 108.79 +habla de conjuntos de cambios). Podemos ver los frentes en un 108.80 +repositorio usando el comando \hgcmd{heads}\ndt{Frentes.}. 108.81 +\interaction{tour.merge.heads} 108.82 + 108.83 +\subsection{Hacer la fusión} 108.84 + 108.85 +% TODO poner interrogante de apertura 108.86 +Qué pasa si tratamos de usar el comando usual, \hgcmd{update}, para 108.87 +actualizar el nuevo frente? 108.88 +\interaction{tour.merge.update} 108.89 +Mercurial nos indica que el comando \hgcmd{update} no hará la fusión; 108.90 +no actualizará el directorio de trabajo cuando considera que lo que 108.91 +deseamos hacer es una fusión, a menos que lo obliguemos a hacerlo. 108.92 +En vez de \hgcmd{update}, usamos el comando \hgcmd{merge} para hacer 108.93 +la fusión entre los dos frentes. 108.94 +\interaction{tour.merge.merge} 108.95 + 108.96 +\begin{figure}[ht] 108.97 + \centering 108.98 + \grafix{tour-merge-merge} 108.99 + \caption{Directorio de trabajo y repositorio durante la fusión, y 108.100 + consignación consecuente} 108.101 + \label{fig:tour-merge:merge} 108.102 +\end{figure} 108.103 + 108.104 +Esto actualiza el directorio de trabajo, de tal forma que contenga los 108.105 +cambios de \emph{ambos} frentes, lo que se ve reflejado tanto en la 108.106 +salida de \hgcmd{parents} como en los contenidos de \filename{hello.c}. 108.107 +\interaction{tour.merge.parents} 108.108 + 108.109 +\subsection{Consignar los resultados de la fusión} 108.110 + 108.111 +Siempre que hacemos una fusión, \hgcmd{parents} mostrará dos padres 108.112 +hasta que consignemos (\hgcmd{commit}) los resultados de la fusión. 108.113 +\interaction{tour.merge.commit} 108.114 +Ahora tenemos una nueva revisión de punta; note que tiene \emph{los 108.115 +dos} frentes anteriores como sus padres. Estos son las mismas 108.116 +revisiones que mostró previamente el comando \hgcmd{parents}. 108.117 +\interaction{tour.merge.tip} 108.118 +En la figura~\ref{fig:tour-merge:merge} usted puede apreciar una 108.119 +representación de lo que pasa en el directorio de trabajo durante la 108.120 +fusión cuando se hace la consignación. Durante la fusión, el 108.121 +directorio de trabajo tiene dos conjuntos de cambios como sus padres, 108.122 +y éstos se vuelven los padres del nuevo conjunto de cambios. 108.123 + 108.124 +\section{Fusionar cambios con conflictos} 108.125 + 108.126 +La mayoría de las fusiones son algo simple, pero a veces usted se 108.127 +encontrará fusionando cambios donde más de uno de ellos afecta las 108.128 +mismas secciones de los mismos ficheros. A menos que ambas 108.129 +modificaciones sean idénticas, el resultado es un \emph{conflicto}, en 108.130 +donde usted debe decidir cómo reconciliar ambos cambios y producir un 108.131 +resultado coherente. 108.132 + 108.133 +\begin{figure}[ht] 108.134 + \centering 108.135 + \grafix{tour-merge-conflict} 108.136 + \caption{Cambios con conflictos a un documento} 108.137 + \label{fig:tour-merge:conflict} 108.138 +\end{figure} 108.139 + 108.140 +La figura~\ref{fig:tour-merge:conflict} ilustra un ejemplo con dos 108.141 +cambios generando conflictos en un documento. Empezamos con una sola 108.142 +versión del fichero; luego hicimos algunos cambios; mientras tanto, 108.143 +alguien más hizo cambios diferentes en el mismo texto. Lo que debemos 108.144 +hacer para resolver el conflicto causado por ambos cambios es decidir 108.145 +cómo debe quedar finalmente el fichero. 108.146 + 108.147 +Mercurial no tiene ninguna utilidad integrada para manejar conflictos. 108.148 +En vez de eso, ejecuta un programa externo llamado \command{hgmerge}. 108.149 +Es un guión de línea de comandos que es instalado junto con Mercurial; 108.150 +usted puede modificarlo para que se comporte como usted lo desee. Por 108.151 +defecto, lo que hace es tratar de encontrar una de varias herramientas 108.152 +para fusionar que es probable que estén instaladas en su sistema. 108.153 +Primero se intenta con unas herramientas para fusionar cambios 108.154 +automáticamente; si esto no tiene éxito (porque la fusión demanda 108.155 +una guía humana) o dichas herramientas no están presentes, el guión 108.156 +intenta con herramientas gráficas para fusionar. 108.157 + 108.158 +También es posible hacer que Mercurial ejecute otro programa o guión 108.159 +en vez de \command{hgmerge}, definiendo la variable de entorno 108.160 +\envar{HGMERGE} con el nombre del programa de su preferencia. 108.161 + 108.162 +\subsection{Usar una herramienta gráfica para fusión} 108.163 + 108.164 +Mi herramienta favorita para hacer fusiones es \command{kdiff3}, y la 108.165 +usaré para describir las características comunes de las herramientas 108.166 +gráficas para hacer fusiones. Puede ver una captura de pantalla de 108.167 +\command{kdiff3} ejecutándose, en la 108.168 +figura~\ref{fig:tour-merge:kdiff3}. El tipo de fusión que la 108.169 +herramienta hace se conoce como \emph{fusión de tres vías}, porque hay 108.170 +tres versiones diferentes del fichero en que estamos interesados. 108.171 +Debido a esto la herramienta divide la parte superior de la ventana en 108.172 +tres paneles. 108.173 +\begin{itemize} 108.174 +\item A la izquierda está la revisión \emph{base} del fichero, p.ej.~la 108.175 + versión más reciente de la que descienden las dos versiones que 108.176 + estamos tratando de fusionar. 108.177 +\item En la mitad está ``nuestra'' versión del fichero, con las 108.178 + modificaciones que hemos hecho. 108.179 +\item A la derecha está la versión del fichero de ``ellos'', la que 108.180 + forma parte del conjunto de cambios que estamos tratando de 108.181 + fusionar. 108.182 +\end{itemize} 108.183 +En el panel inferior se encuentra el \emph{resultado} actual de la 108.184 +fusión. Nuestra tarea es reemplazar todo el texto rojo, que muestra 108.185 +los conflictos sin resolver, con una fusión adecuada de ``nuestra'' 108.186 +versión del fichero y la de ``ellos''. 108.187 + 108.188 +Los cuatro paneles están \emph{enlazados}; si avanzamos vertical o 108.189 +horizontalmente en cualquiera de ellos, los otros son actualizados 108.190 +para mostrar las secciones correspondientes del fichero que tengan 108.191 +asociado. 108.192 + 108.193 +\begin{figure}[ht] 108.194 + \centering 108.195 + \grafix[width=\textwidth]{kdiff3} 108.196 + \caption{Usando \command{kdiff3} para fusionar versiones de un 108.197 + fichero} 108.198 + \label{fig:tour-merge:kdiff3} 108.199 +\end{figure} 108.200 + 108.201 +En cada conflicto del fichero podemos escoger resolverlo usando 108.202 +cualquier combinación del texto de la revisión base, la nuestra, o la 108.203 +de ellos. También podemos editar manualmente el fichero en que queda 108.204 +la fusión, si es necesario hacer cambios adicionales. 108.205 + 108.206 +Hay \emph{muchas} herramientas para fusionar ficheros disponibles. Se 108.207 +diferencian en las plataformas para las que están disponibles, y en 108.208 +sus fortalezas y debilidades particulares. La mayoría están afinadas 108.209 +para fusionar texto plano, mientras que otras están pensadas para 108.210 +formatos de ficheros especializados (generalmente XML). 108.211 + 108.212 +% TODO traduje "worked" como "real" 108.213 +\subsection{Un ejemplo real} 108.214 + 108.215 +En este ejemplo, reproduciremos el historial de modificaciones al 108.216 +fichero de la figura~\ref{fig:tour-merge:conflict} mostrada 108.217 +anteriormente. Empecemos creando un repositorio con la versión base 108.218 +de nuestro documento. 108.219 +\interaction{tour-merge-conflict.wife} 108.220 +Clonaremos el repositorio y haremos un cambio al fichero. 108.221 +\interaction{tour-merge-conflict.cousin} 108.222 +Y haremos otro clon, para simular a alguien más haciendo un cambio al 108.223 +mismo fichero. (Esto introduce la idea de que no es tan inusual hacer 108.224 +fusiones consigo mismo, cuando usted aísla tareas en repositorios 108.225 +separados, y de hecho encuentra conflictos al hacerlo.) 108.226 +\interaction{tour-merge-conflict.son} 108.227 +Ahora que tenemos dos versiones diferentes de nuestro fichero, 108.228 +crearemos un entorno adecuado para hacer la fusión. 108.229 +\interaction{tour-merge-conflict.pull} 108.230 + 108.231 +En este ejemplo, no usaré el comando normal de Mercurial para hacer la 108.232 +fusión (\command{hgmerge}), porque lanzaría mi linda herramienta 108.233 +automatizada para correr ejemplos dentro de una interfaz gráfica de 108.234 +usuario. En vez de eso, definiré la variable de entorno 108.235 +\envar{HGMERGE} para indicarle a Mercurial que use el comando 108.236 +\command{merge}. Este comando forma parte de la instalación base de 108.237 +muchos sistemas Unix y similares. Si usted está ejecutando este 108.238 +ejemplo en su computador, no se moleste en definir \envar{HGMERGE}. 108.239 +\interaction{tour-merge-conflict.merge} 108.240 +Debido a que \command{merge} no puede resolver los conflictos que 108.241 +aparecen, él deja \emph{marcadores de fusión} en el fichero con 108.242 +conflictos, indicando si provienen de nuestra versión o de la de 108.243 +ellos. 108.244 + 108.245 +Mercurial puede saber ---por el código de salida del comando 108.246 +\command{merge}--- que no fue posible hacer la fusión exitosamente, 108.247 +así que nos indica qué comandos debemos ejecutar si queremos rehacer 108.248 +la fusión. Esto puede ser útil si, por ejemplo, estamos ejecutando una 108.249 +herramienta gráfica de fusión y salimos de ella porque nos confundimos 108.250 +o cometimos un error. 108.251 + 108.252 +Si la fusión ---automática o manual--- falla, no hay nada que nos 108.253 +impida ``arreglar'' los ficheros afectados por nosotros mismos, y 108.254 +consignar los resultados de nuestra fusión: 108.255 +% TODO este mercurial no tiene el comando resolve. Revisar si sigue 108.256 +% siendo necesario 108.257 +\interaction{tour-merge-conflict.commit} 108.258 + 108.259 +\section{Simplificar el ciclo jalar-fusionar-consignar} 108.260 +\label{sec:tour-merge:fetch} 108.261 + 108.262 +El proceso de fusionar cambios delineado anteriomente es directo, pero 108.263 +requiere la ejecución de tres comandos en sucesión. 108.264 +\begin{codesample2} 108.265 + hg pull 108.266 + hg merge 108.267 + hg commit -m 'Fusionados cambios remotos' 108.268 +\end{codesample2} 108.269 +En la consignación final usted debe proveer un mensaje adecuado, que 108.270 +casi siempre es un fragmento de texto ``de relleno'' carente de valor 108.271 +particular. 108.272 + 108.273 +Sería agradable reducir la cantidad de pasos necesarios, si fuera 108.274 +posible. De hecho, Mercurial es distribuido junto con una extensión 108.275 +llamada \hgext{fetch}\ndt{Descargar, traer.} que hace precisamente 108.276 +esto. 108.277 + 108.278 +Mercurial cuenta con un mecanismo de extensión flexible que le permite 108.279 +% TODO lets people => permite a usuarios 108.280 +a sus usuarios extender su funcionalidad, manteniendo el núcleo de 108.281 +Mercurial pequeño y fácil de manejar. Algunas extensiones añaden 108.282 +nuevos comandos que usted puede usar desde la línea de comandos, 108.283 +mientras que otros funcionan ``tras bambalinas'', por ejemplo, 108.284 +añadiendo funcionalidad al servidor. 108.285 + 108.286 +La extensión \hgext{fetch} añade un comando llamado, no 108.287 +sorpresivamente, \hgcmd{fetch}. Esta extensión actúa como una 108.288 +combinación de \hgcmd{pull}, \hgcmd{update} y \hgcmd{merge}. Empieza 108.289 +jalando cambios de otro repositorio al repositorio actual. Si 108.290 +encuentra que los cambios añaden un nuevo frente en el repositorio 108.291 +actual, inicia una fusión, y luego consigna el resultado de la misma 108.292 +con un mensaje generado automáticamente. Si no se añadieron nuevos 108.293 +frentes, actualiza el directorio de trabajo con el nuevo conjunto de 108.294 +cambios de punta. 108.295 + 108.296 +Activar la extensión \hgext{fetch} es fácil. Edite su 108.297 +\sfilename{.hgrc}, y vaya a (o cree) la sección 108.298 +\rcsection{extensions}. Luego añada una línea que diga simplemente 108.299 +``\Verb+fetch +''. 108.300 +\begin{codesample2} 108.301 + [extensions] 108.302 + fetch = 108.303 +\end{codesample2} 108.304 +(Normalmente, a la derecha del ``\texttt{=}'' debería aparecer la 108.305 +ubicación de la extensión, pero como el comando \hgext{fetch} es parte 108.306 +de la distribución estándar, Mercurial sabe dónde buscarla.) 108.307 + 108.308 +%%% Local Variables: 108.309 +%%% mode: latex 108.310 +%%% TeX-master: "00book" 108.311 +%%% End:
109.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 109.2 +++ b/es/undo-manual-merge.dot Thu Jan 29 22:00:07 2009 -0800 109.3 @@ -0,0 +1,8 @@ 109.4 +digraph undo_manual { 109.5 + "primer cambio" -> "segundo cambio"; 109.6 + "segundo cambio" -> "tercer cambio"; 109.7 + reversar [label="reversar\nsegundo cambio", shape=box]; 109.8 + "segundo cambio" -> reversar; 109.9 + "tercer cambio" -> "fusión\nmanual"; 109.10 + reversar -> "fusión\nmanual"; 109.11 +}
110.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 110.2 +++ b/es/undo-manual.dot Thu Jan 29 22:00:07 2009 -0800 110.3 @@ -0,0 +1,6 @@ 110.4 +digraph undo_manual { 110.5 + "primer cambio" -> "segundo cambio"; 110.6 + "segundo cambio" -> "tercer cambio"; 110.7 + reversar [label="reversar\nsegundo cambio", shape=box]; 110.8 + "segundo cambio" -> reversar; 110.9 +}
111.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 111.2 +++ b/es/undo-non-tip.dot Thu Jan 29 22:00:07 2009 -0800 111.3 @@ -0,0 +1,9 @@ 111.4 +digraph undo_non_tip { 111.5 + "primer cambio" -> "segundo cambio"; 111.6 + "segundo cambio" -> "tercer cambio"; 111.7 + reversar [label="reversar\nsegundo cambio", shape=box]; 111.8 + "segundo cambio" -> reversar; 111.9 + merge [label="automatizar\nfusión", shape=box]; 111.10 + "tercer cambio" -> fusión; 111.11 + reversar -> fusión; 111.12 +}
112.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 112.2 +++ b/es/undo-simple.dot Thu Jan 29 22:00:07 2009 -0800 112.3 @@ -0,0 +1,4 @@ 112.4 +digraph undo_simple { 112.5 + "primer cambio" -> "segundo cambio"; 112.6 + "segundo cambio" -> "reversar\nsegundo cambio"; 112.7 +}
113.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 113.2 +++ b/es/undo.tex Thu Jan 29 22:00:07 2009 -0800 113.3 @@ -0,0 +1,799 @@ 113.4 +\chapter{Encontrar y arreglar sus equivocaciones} 113.5 +\label{chap:undo} 113.6 + 113.7 +Errar es humano, pero tratar adecuadamente las consecuencias requiere 113.8 +un sistema de control de revisiones de primera categoría. En este 113.9 +capítulo, discutiremos algunas técnicas que puede usar cuando 113.10 +encuentra que hay un problema enraizado en su proyecto. Mercurial 113.11 +tiene unas características poderosas que le ayudarán a isolar las 113.12 +fuentes de los problemas, y a dar cuenta de ellas apropiadamente. 113.13 + 113.14 +\section{Borrar el historial local} 113.15 + 113.16 +\subsection{La consignación accidental} 113.17 + 113.18 +Tengo el problema ocasional, pero persistente de teclear más rápido de 113.19 +lo que pienso, que aveces resulta en consignar un conjunto de cambios 113.20 +incompleto o simplemente malo. En mi caso, el conjunto de cambios 113.21 +incompleto consiste en que creé un nuevo fichero fuente, pero olvidé 113.22 +hacerle \hgcmd{add}. Un conjunto de cambios``simplemente malo'' no es 113.23 +tan común, pero sí resulta muy molesto. 113.24 + 113.25 +\subsection{Hacer rollback una transacción} 113.26 +\label{sec:undo:rollback} 113.27 + 113.28 +En la sección~\ref{sec:concepts:txn}, mencioné que Mercurial trata 113.29 +modificación a un repositorio como una \emph{transacción}. Cada vez 113.30 +que consigna un conjunto de cambios o lo jala de otro repositorio, 113.31 +Mercurial recuerda lo que hizo. Puede deshacer, o hacer \emph{roll back}\ndt{El significado igual que en los 113.32 + ambientes de sistemas manejadores de bases de datos se refiere a 113.33 + la atomicidad e integridad al devolver un conjunto de acciones que 113.34 + permitan dejar el repositorio en un estado consistente previo}, 113.35 +exactamente una de tales acciones usando la orden \hgcmd{rollback}. 113.36 +(Ver en la sección~\ref{sec:undo:rollback-after-push} una anotación 113.37 +importante acerca del uso de esta orden.) 113.38 + 113.39 +A continuación una equivocación que me sucede frecuentemente: 113.40 +consignar un cambio en el cual he creado un nuevo fichero, pero he 113.41 +olvidado hacerle \hgcmd{add}. 113.42 +\interaction{rollback.commit} 113.43 +La salida de \hgcmd{status} después de la consignación confirma 113.44 +inmediatamente este error. 113.45 +\interaction{rollback.status} 113.46 +La consignación capturó los cambios en el fichero \filename{a}, pero 113.47 +no el nuevo fichero \filename{b}. Si yo publicara este conjunto de 113.48 +cambios a un repositorio compartido con un colega, es bastante 113.49 +probable que algo en \filename{a} se refiriera a \filename{b}, el cual 113.50 +podría no estar presente cuando jalen mis cambios del repositorio. Me 113.51 +convertiría el sujeto de cierta indignación. 113.52 + 113.53 +Como sea, la suerte me acompaña---Encontré mi error antes de publicar 113.54 +el conjunto de cambios. Uso la orden \hgcmd{rollback}, y Mercurial 113.55 +hace desaparecer el último conjunto de cambios. 113.56 +\interaction{rollback.rollback} 113.57 +El conjunto de cambios ya no está en el historial del repositorio, y el 113.58 +directorio de trabajo cree que el fichero \filename{a} ha sido 113.59 +modificado. La consignación y el roll back dejaron el directorio de 113.60 +trabajo exactamente como estaba antes de la consignación; el conjunto 113.61 +de cambios ha sido eliminado totlamente. Ahora puedo hacer \hgcmd{add} 113.62 +al fichero \filename{b}, y hacer de nuevo la consignación. 113.63 +\interaction{rollback.add} 113.64 + 113.65 +\subsection{Erroneamente jalado} 113.66 + 113.67 +Mantener ramas de desarrollo separadas de un proyecto en distintos 113.68 +repositorios es una práctica común con Mercurial. Su equipo de 113.69 +desarrollo puede tener un repositorio compartido para la versión ``0.9'' 113.70 +y otra con cambios distintos para la versión ``1.0''. 113.71 + 113.72 +Con este escenario, puede imaginar las consecuencias si tuviera un 113.73 +repositorio local ``0.9'', y jalara accidentalmente los cambios del 113.74 +repositorio compartido de la versión ``1.0'' en este. En el peor de 113.75 +los casos, por falta de atención, es posible que publique tales 113.76 +cambios en el árbol compartido ``0.9'', confundiendo a todo su equipo 113.77 +de trabajo (pero no se preocupe, volveremos a este terrorífico 113.78 +escenario posteriormente). En todo caso, es muy probable que usted se 113.79 +de cuenta inmediatamente, dado que Mercurial mostrará el URL de donde 113.80 +está jalando, o que vea jalando una sospechosa gran cantidad de 113.81 +cambios en el repositorio. 113.82 + 113.83 +La orden \hgcmd{rollback} excluirá eficientemente los conjuntos de 113.84 +cambios que haya acabado de jalar. Mercurial agrupa todos los cambios 113.85 +de un \hgcmd{pull} a una única transacción y bastará con un 113.86 +\hgcmd{rollback} para deshacer esta equivocación. 113.87 + 113.88 +\subsection{Después de publicar, un roll back es futil} 113.89 +\label{sec:undo:rollback-after-push} 113.90 + 113.91 +El valor de \hgcmd{rollback} se anula cuando ha publicado sus cambios 113.92 +a otro repositorio. Un cambio desaparece totalmente al hacer roll back, 113.93 +pero \emph{solamente} en el repositorio en el cual aplica 113.94 +\hgcmd{rollback}. Debido a que un roll back elimina el historial, 113.95 +no hay forma de que la desaparición de un cambio se propague entre 113.96 +repositorios. 113.97 + 113.98 +Si ha publicado un cambio en otro repositorio---particularmente si es 113.99 +un repositorio público---esencialmente está ``en terreno agreste,'' 113.100 +y tendrá que reparar la equivocación de un modo distinto. Lo que 113.101 +pasará si publica un conjunto de cambios en algún sitio, hacer 113.102 +rollback y después volver a jalar del repositorio del cual había 113.103 +publicado, es que el conjunto de cambios reaparecerá en su repositorio. 113.104 + 113.105 +(Si está absolutamente segruro de que el conjunto de cambios al que 113.106 +desea hacer rollback es el cambio más reciente del repositorio en el 113.107 +cual publicó, \emph{y} sabe que nadie más pudo haber jalado de tal 113.108 +repositorio, puede hacer rollback del conjunto de cambios allí, pero 113.109 +es mejor no confiar en una solución de este estilo. Si lo hace, tarde 113.110 +o temprano un conjunto de cambios logrará colarse en un repositorio 113.111 +que usted no controle directamente (o del cual se ha olvidado), y 113.112 +volverá a hostigarle.) 113.113 + 113.114 +\subsection{Solamente hay un roll back} 113.115 + 113.116 +Mercurial almacena exactamente una transacción en su bitácora de 113.117 +transacciones; tal transacción es la más reciente de las que haya 113.118 +ocurrido en el repositorio. Esto significa que solamente puede hacer 113.119 +roll back a una transacción. Si espera poder hacer roll back a una 113.120 +transacción después al antecesor, observará que no es el 113.121 +comportamiento que obtendrá. 113.122 +\interaction{rollback.twice} 113.123 +Una vez que haya aplicado un rollback en una transacción a un 113.124 +repositorio, no podrá volver a hacer rollback hasta que haga una 113.125 +consignación o haya jalado. 113.126 + 113.127 +\section{Revertir un cambio equivocado} 113.128 + 113.129 +Si modifica un fichero y se da cuenta que no quería realmente cambiar 113.130 +tal fichero, y todavía no ha consignado los cambios, la orden 113.131 +necesaria es \hgcmd{revert}. Observa el conjunto de cambios padre del 113.132 +directorio y restaura los contenidos del fichero al estado de tal 113.133 +conjunto de cambios. (Es una forma larga de decirlo, usualmente 113.134 +deshace sus modificaciones.) 113.135 + 113.136 +Ilustremos como actúa la orden \hgcmd{revert} con un ejemplo 113.137 +pequeño. Comenzaremos modificando un fichero al cual Mercurial ya está 113.138 +siguiendo. 113.139 +\interaction{daily.revert.modify} 113.140 +Si no queremos ese cambio, podemos aplicar \hgcmd{revert} al fichero. 113.141 +\interaction{daily.revert.unmodify} 113.142 +La orden \hgcmd{revert} nos brinda un grado adicional de seguridad 113.143 +guardando nuestro fichero modificado con la extensión \filename{.orig}. 113.144 +\interaction{daily.revert.status} 113.145 + 113.146 +Este es un resumen de casos en los cuales la orden \hgcmd{revert} es 113.147 +de utilidad. Describiremos cada uno de ellos con más detalle en la 113.148 +sección siguiente. 113.149 +\begin{itemize} 113.150 +\item Si usted modifica un fichero, lo restaurará a su estado sin 113.151 + modificación previo. 113.152 +\item Si usted hace \hgcmd{add} a un fichero, revertirá el estado de 113.153 + ``adicionado'' del fichero, pero no lo tocará 113.154 +\item Si borra un fichero sin decirle a Mercurial, restaurará el 113.155 + fichero con sus contenidos sin modificación. 113.156 +\item Si usa la orden \hgcmd{remove} para eliminar un fichero, deshará 113.157 + el estado ``removido'' del fichero, y lo restaurará con sus 113.158 + contenidos sin modificación. 113.159 +\end{itemize} 113.160 + 113.161 +\subsection{Errores al administrar ficheros} 113.162 +\label{sec:undo:mgmt} 113.163 + 113.164 +La orden \hgcmd{revert} es útil para más que ficheros modificados. Le 113.165 +permite reversar los resultados de todas las órdenes de administración 113.166 +de ficheros que provee Mercurial---\hgcmd{add}, \hgcmd{remove}, y las 113.167 +demás. 113.168 + 113.169 +Si usted hace \hgcmd{add} a un fichero, y no deseaba que Mercurial le 113.170 +diera seguimiento, use \hgcmd{revert} para deshacer la adición. No se 113.171 +preocupe; Mercurial no modificará de forma alguna el fichero. 113.172 +Solamente lo ``desmarcará''. 113.173 +\interaction{daily.revert.add} 113.174 + 113.175 +De forma similar, Si le solicita a Mercurial hacer \hgcmd{remove} a un 113.176 +fichero, puede usar \hgcmd{revert} para restarurarlo a los contenidos 113.177 +que tenía la revisión padre del directorio de trabajo. 113.178 +\interaction{daily.revert.remove} 113.179 +Funciona de la misma manera para un fichero que usted haya eliminado 113.180 +manualmente, sin decirle a Mercurial (recuerde que en la terminología 113.181 +de Mercurial esta clase de fichero se llama ``faltante''). 113.182 +\interaction{daily.revert.missing} 113.183 + 113.184 +Si usted revierte un \hgcmd{copy}, el fichero a donde se copió 113.185 +permanece en su directorio de trabajo, pero sin seguimiento. Dado que 113.186 +una copia no afecta el fichero fuente de copiado de ninguna maner, 113.187 +Mercurial no hace nada con este. 113.188 +\interaction{daily.revert.copy} 113.189 + 113.190 +\subsubsection{Un caso ligeramente especial:revertir un renombramiento} 113.191 + 113.192 +Si hace \hgcmd{rename} a un fichero, hay un detalle que debe tener en 113.193 +cuenta. Cuando aplica \hgcmd{revert} a un cambio de nombre, no es 113.194 +suficiente proveer el nombre del fichero destino, como puede verlo en 113.195 +el siguiente ejemplo. 113.196 +\interaction{daily.revert.rename} 113.197 +Como puede ver en la salida de \hgcmd{status}, el fichero con el nuevo 113.198 +nombre no se identifica más como agregado, pero el fichero con el 113.199 +nombre-\emph{inicial} se elimna! Esto es contra-intuitivo (por lo 113.200 +menos para mí), pero por lo menos es fácil arreglarlo. 113.201 +\interaction{daily.revert.rename-orig} 113.202 +Por lo tanto, recuerde, para revertir un \hgcmd{rename}, debe proveer 113.203 +\emph{ambos} nombres, la fuente y el destino. 113.204 + 113.205 +% TODO: the output doesn't look like it will be removed! 113.206 + 113.207 +(A propósito, si elimina un fichero, y modifica el fichero con el 113.208 +nuevo nombre, al revertir ambos componentes del renombramiento, cuando 113.209 +Mercurial restaure el fichero que fue eliminado como parte del 113.210 +renombramiento, no será modificado. 113.211 +Si necesita que las modificaciones en el fichero destino del 113.212 +renombramiento se muestren, no olvide copiarlas encima.) 113.213 + 113.214 +Estos aspectos engorrosos al revertir un renombramiento se constituyen 113.215 +discutiblemente en un fallo de Mercurial. 113.216 + 113.217 +\section{Tratar cambios consignados} 113.218 + 113.219 +Considere un caso en el que ha consignado el cambio $a$, y otro cambio 113.220 +$b$ sobre este; se ha dado cuenta que el cambio $a$ era 113.221 +incorrecto. Mercurial le permite ``retroceder'' un conjunto de cambios 113.222 +completo automáticamente, y construir bloques que le permitan revertir 113.223 +parte de un conjunto de cambios a mano. 113.224 + 113.225 +Antes de leer esta sección, hay algo para tener en cuenta: la orden 113.226 +\hgcmd{backout} deshace cambios \emph{adicionando} al historial, sin 113.227 +modificar o borrar. Es la herramienta correcta si está arreglando 113.228 +fallos, pero no si está tratando de deshacer algún cambio que tiene 113.229 +consecuencias catastróficas. Para tratar con esos, vea la sección~\ref{sec:undo:aaaiiieee}. 113.230 + 113.231 +\subsection{Retroceder un conjunto de cambios} 113.232 + 113.233 +La orden \hgcmd{backout} le permite ``deshacer'' los efectos de todo 113.234 +un conjunto de cambios de forma automatizada. Dado que el historial de 113.235 +Mercurial es inmutable, esta orden \emph{no} se deshace del conjunto 113.236 +de cambios que usted desea deshacer. En cambio, crea un nuevo 113.237 +conjunto de cambios que \emph{reversa} el conjunto de cambios que 113.238 +usted indique. 113.239 + 113.240 +La operación de la orden \hgcmd{backout} es un poco intrincada, y lo 113.241 +ilustraremos con algunos ejemplos. Primero crearemos un repositorio 113.242 +con algunos cambios sencillos. 113.243 +\interaction{backout.init} 113.244 + 113.245 +La orden \hgcmd{backout} toma un ID de conjunto de cambios como su 113.246 +argumento; el conjunto de cambios a retroceder. Normalmente 113.247 +\hgcmd{backout} le ofrecerá un editor de texto para escribir el 113.248 +mensaje de la consignación, para dejar un registro de por qué está 113.249 +retrocediendo. En este ejemplo, colocamos un mensaje en la 113.250 +consignación usando la opción \hgopt{backout}{-m}. 113.251 + 113.252 +\subsection{Retroceder el conjunto de cambios punta} 113.253 + 113.254 +Comenzamos retrocediendo el último conjunto de cambios que consignamos. 113.255 +\interaction{backout.simple} 113.256 +Puede ver que la segunda línea de \filename{myfile} ya no está 113.257 +presente. La salida de \hgcmd{log} nos da una idea de lo que la orden 113.258 +\hgcmd{backout} ha hecho. 113.259 +\interaction{backout.simple.log} 113.260 +Vea que el nuevo conjunto de cambios que \hgcmd{backout} ha creado es 113.261 +un hijo del conjunto de cambios que retrocedimos. Es más sencillo de 113.262 +ver en la figura~\ref{fig:undo:backout}, que presenta una vista 113.263 +gráfica del historial de cambios. Como puede ver, el historial es 113.264 +bonito y lineal. 113.265 + 113.266 +\begin{figure}[htb] 113.267 + \centering 113.268 + \grafix{undo-simple} 113.269 + \caption{Retroceso de un cambio con la orden \hgcmd{backout}} 113.270 + \label{fig:undo:backout} 113.271 +\end{figure} 113.272 + 113.273 +\subsection{Retroceso de un cambio que no es la punta} 113.274 + 113.275 +Si desea retrocede un cambio distinto al último que ha consignado, use 113.276 +la opción \hgopt{backout}{--merge} a la orden \hgcmd{backout}. 113.277 +\interaction{backout.non-tip.clone} 113.278 +Que resulta en un retroceso de un conjunto de cambios ``en un sólo 113.279 +tiro'', una operación que resulta normalmente rápida y sencilla. 113.280 +\interaction{backout.non-tip.backout} 113.281 + 113.282 +Si ve los contenidos del fichero \filename{myfile} después de 113.283 +finalizar el retroceso, verá que el primer y el tercer cambio están 113.284 +presentes, pero no el segundo. 113.285 +\interaction{backout.non-tip.cat} 113.286 + 113.287 +Como lo muestra el historial gráfico en la 113.288 +figura~\ref{fig:undo:backout-non-tip}, Mercurial realmente consigna 113.289 +\emph{dos} cambios en estas situaciones (los nodos encerrados en una 113.290 +caja son aquellos que Mercurial consigna automaticamente). Antes de 113.291 +que Mercurial comience el proceso de retroceso, primero recuerda cuál 113.292 +es el padre del directorio de trabajo. Posteriormente hace un 113.293 +retroceso al conjunto de cambios objetivo y lo consigna como un 113.294 +conjunto de cambios. Finalmente, fusiona con el padre anterior del 113.295 +directorio de trabajo, y consigna el resultado de la fusión. 113.296 + 113.297 +% TODO: to me it looks like mercurial doesn't commit the second merge automatically! 113.298 + 113.299 +\begin{figure}[htb] 113.300 + \centering 113.301 + \grafix{undo-non-tip} 113.302 + \caption{Retroceso automatizado de un cambio a algo que no es la punta con la orden \hgcmd{backout}} 113.303 + \label{fig:undo:backout-non-tip} 113.304 +\end{figure} 113.305 + 113.306 +El resultado es que usted termina ``donde estaba'', solamente con un 113.307 +poco de historial adicional que deshace el efecto de un conjunto de 113.308 +cambios que usted quería evitar. 113.309 + 113.310 +\subsubsection{Use siempre la opción \hgopt{backout}{--merge}} 113.311 + 113.312 +De hecho, dado que la opción \hgopt{backout}{--merge} siempre hara lo 113.313 +``correcto'' esté o no retrocediendo el conjunto de cambios punta 113.314 +(p.e.~no tratará de fusionar si está retrocediendo la punta, dado que 113.315 +no es necesario), usted debería usar \emph{siempre} esta opción cuando 113.316 +ejecuta la orden \hgcmd{backout}. 113.317 + 113.318 +\subsection{Más control sobre el proceso de retroceso} 113.319 + 113.320 +A pesar de que recomiendo usar siempre la opción 113.321 +\hgopt{backout}{--merge} cuando está retrocediendo un cambio, la orden 113.322 +\hgcmd{backout} le permite decidir cómo mezclar un retroceso de un 113.323 +conjunto de cambios. Es muy extraño que usted necestite tomar control 113.324 +del proceso de retroceso de forma manual, pero puede ser útil entender 113.325 +lo que la orden \hgcmd{backout} está haciendo automáticamente para 113.326 +usted. Para ilustrarlo, clonemos nuestro primer repositorio, pero 113.327 +omitamos el retroceso que contiene. 113.328 + 113.329 +\interaction{backout.manual.clone} 113.330 +Como en el ejemplo anterior, consignaremos un tercer cambio, después 113.331 +haremos retroceso de su padre, y veremos qué pasa. 113.332 +\interaction{backout.manual.backout} 113.333 +Nuestro nuevo conjunto de cambios es de nuevo un descendiente del 113.334 +conjunto de cambio que retrocedimos; es por lo tanto una nueva cabeza, 113.335 +\emph{no} un descendiente del conjunto de cambios que era la punta. La 113.336 +orden \hgcmd{backout} fue muy explícita diciéndolo. 113.337 +\interaction{backout.manual.log} 113.338 + 113.339 +De nuevo, es más sencillo lo que pasó viendo una gráfica del 113.340 +historial de revisiones, en la figura~\ref{fig:undo:backout-manual}. 113.341 +Esto nos aclara que cuando usamos \hgcmd{backout} para retroceder un 113.342 +cambio a algo que no sea la punta, Mercurial añade una nueva cabeza al 113.343 +repositorio (el cambio que consignó está encerrado en una caja). 113.344 + 113.345 +\begin{figure}[htb] 113.346 + \centering 113.347 + \grafix{undo-manual} 113.348 + \caption{Retroceso usando la orden \hgcmd{backout}} 113.349 + \label{fig:undo:backout-manual} 113.350 +\end{figure} 113.351 + 113.352 +Después de que la orden \hgcmd{backout} ha terminado, deja un nuevo 113.353 +conjunto de cambios de ``retroceso'' como el padre del directorio de trabajo. 113.354 +\interaction{backout.manual.parents} 113.355 +Ahora tenemos dos conjuntos de cambios aislados. 113.356 +\interaction{backout.manual.heads} 113.357 + 113.358 +Reflexionemos acerca de lo que esperamos ver como contenidos de 113.359 +\filename{myfile}. El primer cambio debería estar presente, porque 113.360 +nunca le hicimos retroceso. El segundo cambio debió desaparecer, 113.361 +puesto que es el que retrocedimos. Dado que la gráfica del historial 113.362 +muestra que el tercer camlio es una cabeza separada, \emph{no} 113.363 +esperamos ver el tercer cambio presente en \filename{myfile}. 113.364 +\interaction{backout.manual.cat} 113.365 +Para que el tercer cambio esté en el fichero, hacemos una fusión usual 113.366 +de las dos cabezas. 113.367 +\interaction{backout.manual.merge} 113.368 +Después de eso, el historial gráfica de nuestro repositorio luce como 113.369 +la figura~\ref{fig:undo:backout-manual-merge}. 113.370 + 113.371 +\begin{figure}[htb] 113.372 + \centering 113.373 + \grafix{undo-manual-merge} 113.374 + \caption{Fusión manual de un retroceso} 113.375 + \label{fig:undo:backout-manual-merge} 113.376 +\end{figure} 113.377 + 113.378 +\subsection{Por qué \hgcmd{backout} hace lo que hace} 113.379 + 113.380 +Esta es una descripción corta de cómo trabaja la orden \hgcmd{backout}. 113.381 +\begin{enumerate} 113.382 +\item Se asegura de que el directorio de trabajo es ``limpio'', esto 113.383 + es, que la salida de \hgcmd{status} debería ser vacía. 113.384 +\item Recuerda el padre actual del directorio de trabajo. A este 113.385 + conjunto de cambio lo llamaremos \texttt{orig} 113.386 +\item Hace el equivalente de un \hgcmd{update} para sincronizar el 113.387 + directorio de trabajo con el conjunto de cambios que usted quiere 113.388 + retroceder. Lo llamaremos \texttt{backout} 113.389 +\item Encuentra el padre del conjunto de cambios. Lo llamaremos 113.390 + \texttt{parent}. 113.391 +\item Para cada fichero del conjunto de cambios que el 113.392 + \texttt{retroceso} afecte, hará el equivalente a 113.393 + \hgcmdargs{revert}{-r parent} sobre ese fichero, para restaurarlo a 113.394 + los contenidos que tenía antes de que el conjunto de cambios fuera 113.395 + consignado. 113.396 +\item Se consigna el resultado como un nuevo conjunto de cambios y 113.397 + tiene a \texttt{backout} como su padre. 113.398 +\item Si especifica \hgopt{backout}{--merge} en la línea de comandos, 113.399 + se fusiona con \texttt{orig}, y se consigna el resultado de la 113.400 + fusión. 113.401 +\end{enumerate} 113.402 + 113.403 +Una vía alternativa de implementar la orden \hgcmd{backout} sería usar 113.404 +\hgcmd{export} sobre el conjunto de cambios a retroceder como un diff 113.405 +y después usar laa opción \cmdopt{patch}{--reverse} de la orden 113.406 +\command{patch} para reversar el efecto del cambio sin molestar el 113.407 +directorio de trabajo. Suena mucho más simple, pero no funcionaría 113.408 +bien ni de cerca. 113.409 + 113.410 +La razón por la cual \hgcmd{backout} hace una actualización, una 113.411 +consignación, una fusión y otra consignación es para dar a la 113.412 +maquinaria de fusión la mayor oportunidad de hacer un buen trabajo 113.413 +cuando se trata con todos los cambios \emph{entre} el cambio que está 113.414 +retrocediendo y la punta actual. 113.415 + 113.416 +Si está retrocediendo un conjunto de cambios que está a unas ~100 113.417 +atrás en su historial del proyecto, las posibilidades de que una orden 113.418 +\command{patch} sea capaz de ser aplicada a un diff reverso, 113.419 +claramente no son altas, porque los cambios que intervienen podrían 113.420 +``no coincidir con el contexto'' que \command{patch} usa para 113.421 +determinar si puede aplicar un parche (si esto suena como cháchara, 113.422 +vea una discusión de la orden \command{patch} en \ref{sec:mq:patch}). 113.423 +Adicionalmente, la maquinaria de fusión de Mercurial manejará ficheros 113.424 +y directorios renombrados, cambios de permisos, y modificaciones a 113.425 +ficheros binarios, nada de lo cual la orden \command{patch} puede manejar. 113.426 + 113.427 +\section{Cambios que nunca debieron ocurrir} 113.428 +\label{sec:undo:aaaiiieee} 113.429 + 113.430 +En la mayoría de los casos, la orden \hgcmd{backout} es exactamente lo 113.431 +que necesita para deshacer los efectos de un cambio. Deja un registro 113.432 +permanente y exacto de lo que usted hizo, cuando se consignó el 113.433 +conjunto de cambios original y cuando se hizo la limpieza. 113.434 + 113.435 +En ocasiones particulares, puede haber consignado un cambio que no 113.436 +debería estar de ninguna forma en el repositorio. Por ejemplo, sería 113.437 +muy inusual, y considerado como una equivocación, consignar los 113.438 +ficheros objeto junto con el código fuente. Los ficheros objeto no 113.439 +tienen valor intrínseco y son \emph{grandes}, por lo tanto aumentan el 113.440 +tamaño del repositorio y la cantidad de tiempo que se emplea al clonar 113.441 +o jalar cambios. 113.442 + 113.443 +Antes de discutir las opciones que tiene si consignó cambio del tipo 113.444 +``bolsa de papel deschable'' (el tipo que es tan malo que le gustaría 113.445 +colocarse una bolsa de papel desechable en su cabeza), permítame 113.446 +discutir primero unas aproximaciones que probablemente no funcionen. 113.447 + 113.448 +Dado que Mercurial trata de forma acumulativa al historial---cada 113.449 +cambio se coloca encima de todos los cambios que le 113.450 +preceden---usualmente usted no puede hacer que unos cambios desastrosos 113.451 +desaparezcan. La única excepción es cuando usted ha acabado de 113.452 +consignar un cambio y este no ha sido publicado o jalado en otro 113.453 +repositorio. Ahí es cuando puede usar la orden \hgcmd{rollback} con 113.454 +seguridad, como detallé en la sección~\ref{sec:undo:rollback}. 113.455 + 113.456 +Después de que usted haya publicado un cambio en otro repositorio, usted 113.457 +\emph{podría} usar la orden \hgcmd{rollback} para hacer que en su copia 113.458 +local desaparezca el cambio, pero no tendrá las consecuencias que 113.459 +desea. El cambio estará presente en un repositorio remoto, y 113.460 +reaparecerá en su repositorio local la próxima vez que jale 113.461 + 113.462 +Si una situación como esta se presenta, y usted sabe en qué 113.463 +repositorios su mal cambio se ha propagado, puede \emph{intentar} 113.464 +deshacerse del conjunto de cambios de \emph{todos} los repositorios en 113.465 +los que se pueda encontrar. Esta por supuesto, no es una solución 113.466 +satisfactoria: si usted deja de hacerlo en un solo repositorio, 113.467 +mientras esté eliminándolo, el cambio todavía estará ``allí afuera'', 113.468 +y podría propagarse más tarde. 113.469 + 113.470 +Si ha consignado uno o más cambios \emph{después} del cambio que desea 113.471 +desaparecer, sus opciones son aún más reducidas. Mercurial no provee 113.472 +una forma de ``cabar un hueco'' en el historial, dejando los conjuntos 113.473 +de cambios intactos. 113.474 + 113.475 +%Dejamos de traducir lo que viene a continuación, porque será 113.476 +%modificado por upstream... 113.477 + 113.478 +XXX This needs filling out. The \texttt{hg-replay} script in the 113.479 +\texttt{examples} directory works, but doesn't handle merge 113.480 +changesets. Kind of an important omission. 113.481 + 113.482 +\subsection{Cómo protegerse de cambios que han ``escapado''} 113.483 + 113.484 +Si ha consignado cambios a su repositorio local y estos han sido 113.485 +publicados o jalados en cualquier otro sitio, no es necesariamente un 113.486 +desastre. Puede protegerse de antemano de ciertas clases de conjuntos 113.487 +de cambios malos. Esto es particularmente sencillo si su equipo de 113.488 +trabajo jala cambios de un repositorio central. 113.489 + 113.490 +Al configurar algunos ganchos en el repositorio central para validar 113.491 +conjuntos de cambios (ver capítulo~\ref{chap:hook}), puede prevenir la 113.492 +publicación automáticamente de cierta clase de cambios malos. Con tal 113.493 +configuración, cierta clase de conjuntos de cambios malos tenderán 113.494 +naturalmente a``morir'' debido a que no pueden propagarse al 113.495 +repositorio central. Esto sucederá sin necesidad de intervención 113.496 +explícita. 113.497 + 113.498 +Por ejemplo, un gancho de cambios de entrada que verifique que un 113.499 +conjunto de cambios compila, puede prevenir que la gente ``rompa 113.500 +la compilación'' inadvertidamente. 113.501 + 113.502 +\section{Al encuentro de la fuente de un fallo} 113.503 +\label{sec:undo:bisect} 113.504 + 113.505 +Aunque es muy bueno poder retroceder el conjunto de cambios que 113.506 +originó un fallo, se requiere que usted sepa cual conjunto de cambios 113.507 +retroceder. Mercurial brinda una orden invaluable, llamada 113.508 +\hgcmd{bisect}, que ayuda a automatizar este proceso y a alcanzarlo 113.509 +muy eficientemente. 113.510 + 113.511 +La idea tras la orden \hgcmd{bisect} es que el conjunto de cambios que 113.512 +ha introducido un cambio de comportamiento pueda identificarse con una 113.513 +prueba binaria sencilla. No tiene que saber qué pieza de código 113.514 +introdujo el cambio, pero si requiere que sepa cómo probar la 113.515 +existencia de un fallo. La orden \hgcmd{bisect} usa su prueba para 113.516 +dirigir su búsqueda del conjunto de cambios que introdujo el código 113.517 +causante del fallo. 113.518 + 113.519 +A continuación un conjunto de escenarios que puede ayudarle a entender 113.520 +cómo puede aplicar esta orden. 113.521 +\begin{itemize} 113.522 +\item La versión más reciente de su programa tiene un fallo que usted 113.523 + recuerda no estaba hace unas semanas, pero no sabe cuándo fue 113.524 + introducido. En este caso, su prueba binaria busca la presencia de 113.525 + tal fallo. 113.526 +\item Usted arregló un fallo en un apurto, y es hora de dar por 113.527 + cerrado el caso en la base de datos de fallos de su equipo de 113.528 + trabajo. La base de datos de fallos requiere el ID del conjunto de 113.529 + cambios que permita dar por cerrado el caso, pero usted no recuerda 113.530 + qué conjunto de cambios arregló tal fallo. De nuevo la prueba 113.531 + binaria revisa la presencia del fallo. 113.532 +\item Su programa funciona correctamente, pero core ~15\% más lento 113.533 + que la última vez que lo midió. Usted desea saber qué conjunto de 113.534 + cambios introdujo esta disminución de desempeño. En este caso su 113.535 + prueba binaria mide el desempeño de su programa, para ver dónde es 113.536 + ``rápido'' y dónde es ``lento''. 113.537 +\item Los tamaños de los componentes del proyecto que usted lleva se 113.538 + expandieron recientemente, y sospecha que algo cambio en la forma en 113.539 + que se construye su proyecto. 113.540 +\end{itemize} 113.541 + 113.542 +Para estos ejemplos debería ser claro que la orden \hgcmd{bisect} 113.543 +es útil no solamente para encontrar la fuente de los fallos. Puede 113.544 +usarla para encontrar cualquier ``propiedad emergente'' de un 113.545 +repositorio (Cualquier cosa que usted no pueda encontrar con una 113.546 +búsqueda de texto sencilla sobre los ficheros en el árbol) para la 113.547 +cual pueda escribir una prueba binaria. 113.548 + 113.549 +A continuación introduciremos algo terminología, para aclarar qué 113.550 +partes del proceso de búsqueda son su responsabilidad y cuáles de 113.551 +Mercurial. Una \emph{prueba} es algo que \emph{usted} ejecuta cuando 113.552 +\hgcmd{bisect} elige un conjunto de cambios. Un \emph{sondeo} es lo que 113.553 +\hgcmd{bisect} ejecuta para decidir si una revisión es buena. Finalmente, 113.554 +usaremos la palabra ``biseccionar', en frases como ``buscar con la 113.555 +orden \hgcmd{bisect}''. 113.556 + 113.557 +Una forma sencilla de automatizar el proceso de búsqueda sería probar 113.558 +cada conjunto de cambios. Lo cual escala muy poco. Si le tomó diez 113.559 +minutos hacer pruebas sobre un conjunto de cambios y tiene 10.000 113.560 +conjuntos de cambios en su repositorio, esta aproximación exhaustiva 113.561 +tomaría en promedio~35 \emph{días} para encontrar el conjunto de 113.562 +cambios que introdujo el fallo. Incluso si supiera que el fallo se 113.563 +introdujo en un de los últimos 500 conjuntos de cambios y limitara la 113.564 +búsqueda a ellos, estaría tomabdi más de 40 horas para encontrar al 113.565 +conjunto de cambios culpable. 113.566 + 113.567 +La orden \hgcmd{bisect} usa su conocimiento de la ``forma'' del 113.568 +historial de revisiones de su proyecto para hacer una búsqueda 113.569 +proporcional al \emph{logaritmo} del número de conjunto de cambios a 113.570 +revisar (el tipo de búsqueda que realiza se llama búsqueda 113.571 +binaria). Con esta aproximación, el buscar entre 10.000 conjuntos de 113.572 +cambios tomará menos de 3 horas, incluso a diez minutos por prueba (La 113.573 +búsqueda requerirá cerca de 14 pruebas). Al limitar la búsqueda a la 113.574 +última centena de conjuntos de cambios, tomará a lo sumo una 113.575 +hora (Apenas unas 7 pruebas). 113.576 + 113.577 +La orden \hgcmd{bisect} tiene en cuenta la naturaleza ``ramificada'' 113.578 +del historial de revisiones del proyecto con Mercurial, así que no 113.579 +hay problemas al tratar con ramas, fusiones o cabezas múltiples en un 113.580 +repositorio. Puede evitar ramas enteras de historial con un solo 113.581 +sondeo. 113.582 + 113.583 +\subsection{Uso de la orden \hgcmd{bisect}} 113.584 + 113.585 +A continuación un ejemplo de \hgcmd{bisect} en acción. 113.586 + 113.587 +\begin{note} 113.588 + En las versiones 0.9.5 y anteriores de Mercurial, \hgcmd{bisect} no 113.589 + era una orden incluída en la distribución principal: se ofrecía como 113.590 + una extensión de Mercurial. Esta sección describe la orden embebida 113.591 + y no la extensión anterior. 113.592 +\end{note} 113.593 + 113.594 +Creamos un repostorio para probar el comando \hgcmd{bisect} de forma 113.595 +aislada 113.596 +\interaction{bisect.init} 113.597 +Simularemos de forma sencilla un proyecto con un fallo: haremos 113.598 +cambios triviales en un ciclo, e indicaremos que un cambio específico 113.599 +sea el ``fallo''. Este ciclo crea 35 conjuntos de cambios, cada uno 113.600 +añade un único fichero al repositorio. Representaremos nuestro ``fallo'' 113.601 +con un fichero que contiene el texto ``tengo un gub''. 113.602 +\interaction{bisect.commits} 113.603 + 113.604 +A continuación observaremos cómo usar la orden \hgcmd{bisect}. Podemos 113.605 +usar el mecanismo de ayuda embebida que trae Mercurial. 113.606 +\interaction{bisect.help} 113.607 + 113.608 +La orden \hgcmd{bisect} trabaja en etapas, de la siguiente forma: 113.609 +\begin{enumerate} 113.610 +\item Usted ejecuta una prueba binaria. 113.611 + \begin{itemize} 113.612 + \item Si la prueba es exitosa, usted se lo indicará a \hgcmd{bisect} 113.613 + ejecutando la orden \hgcmdargs{bisect}{good}. 113.614 + \item Si falla, ejecutará la orden \hgcmdargs{bisect}{--bad}. 113.615 + \end{itemize} 113.616 +\item La orden usa su información para decidir qué conjuntos de 113.617 + cambios deben probarse a continuación. 113.618 +\item Actualiza el directorio de trabajo a tal conjunto de cambios y 113.619 + el proceso se lleva a cabo de nuevo. 113.620 +\end{enumerate} 113.621 +El proceso termina cuando \hgcmd{bisect} identifica un único conjunto 113.622 +de cambios que marca el punto donde se encontró la transición de 113.623 +``exitoso'' a ``fallido''. 113.624 + 113.625 +Para comenzar la búsqueda, es indispensable ejecutar la orden 113.626 +\hgcmdargs{bisect}{--reset}. 113.627 +\interaction{bisect.search.init} 113.628 + 113.629 +En nuestro caso, la prueba binaria es sencilla: revisamos si el 113.630 +fichero en el repositorio contiene la cadena ``tengo un gub''. Si la 113.631 +tiene, este conjunto de cambios contiene aquel que ``causó el fallo''. 113.632 +Por convención, un conjunto de cambios que tiene la propiedad que 113.633 +estamos buscando es ``malo'', mientras que el otro que no la tiene es 113.634 +``bueno''. 113.635 + 113.636 +En la mayoría de casos, la revisión del directorio actual (usualmente 113.637 +la punta) exhibe el problema introducido por el cambio con el fallo, 113.638 +por lo tanto la marcaremos como ``mala''. 113.639 +\interaction{bisect.search.bad-init} 113.640 + 113.641 +Nuestra próxima tarea es nominar al conjunto de cambios que sabemos 113.642 +\emph{no} tiene el fallo; la orden \hgcmd{bisect} ``acotará'' su 113.643 +búsqueda entre el primer par de conjuntos de cambios buenos y malos. 113.644 +En nuestro caso, sabemos que la revisión~10 no tenía el fallo. (Más 113.645 +adelante diré un poco más acerca de la elección del conjunto de 113.646 +cambios ``bueno''.) 113.647 +\interaction{bisect.search.good-init} 113.648 + 113.649 +Note que esta orden mostró algo. 113.650 +\begin{itemize} 113.651 +\item Nos dijo cuántos conjuntos de cambios debe considerar antes de 113.652 + que pueda identifica aquel que introdujo el fallo, y cuántas pruebas 113.653 + se requerirán. 113.654 +\item Actualizó el directorio de trabajo al siguiente conjunto de 113.655 + cambios, y nos dijo qué conjunto de cambios está evaluando. 113.656 +\end{itemize} 113.657 + 113.658 +Ahora ejecutamos nuestra prueba en el directorio de trabajo. Usamos la 113.659 +orden \command{grep} para ver si nuestro fichero ``malo'' está 113.660 +presente en el directorio de trabajo. Si lo está, esta revisión es 113.661 +mala; si no esta revisión es buena. 113.662 +\interaction{bisect.search.step1} 113.663 + 113.664 +Esta prueba luce como candidata perfecta para automatizarse, por lo 113.665 +tanto la convertimos en una función de interfaz de comandos. 113.666 +\interaction{bisect.search.mytest} 113.667 +Ahora podemos ejecutar un paso entero de pruebas con un solo comando, 113.668 +\texttt{mytest}. 113.669 +\interaction{bisect.search.step2} 113.670 +Unas invocaciones más de nuestra prueba, y hemos terminado. 113.671 +\interaction{bisect.search.rest} 113.672 + 113.673 +Aunque teníamos unos~40 conjuntos de cambios en los cuales buscar, la 113.674 +orden \hgcmd{bisect} nos permitió encontrar el conjunto de cambios que 113.675 +introdujo el ``fallo'' con sólo cinco pruebas. Porque el número de 113.676 +pruebas que la orden \hgcmd{bisect} ejecuta crece logarítmicamente con 113.677 +la cantidad de conjuntos de cambios a buscar, la ventaja que esto 113.678 +tiene frente a la búsqueda por``fuerza bruta'' crece con cada 113.679 +conjunto de cambios que usted adicione. 113.680 + 113.681 +\subsection{Limpieza después de la búsqueda} 113.682 + 113.683 +Cuando haya terminado de usar la orden \hgcmd{bisect} en un 113.684 +repositorio, puede usar la orden \hgcmdargs{bisect}{reset} para 113.685 +deshacerse de la información que se estaba usando para lograr la 113.686 +búsqueda. Lar orden no usa mucho espacio, así que no hay problema si 113.687 +olvida ejecutar la orden. En todo caso, \hgcmd{bisect} no le 113.688 +permitirá comenzar una nueva búsqueda sobre el repositorio hasta que 113.689 +no aplique \hgcmdargs{bisect}{reset}. 113.690 +\interaction{bisect.search.reset} 113.691 + 113.692 +\section{Consejos para encontrar fallos efectivamente} 113.693 + 113.694 +\subsection{Dar una entrada consistente} 113.695 + 113.696 +La orden \hgcmd{bisect} requiere que usted ofrezca un reporte correcto 113.697 +del resultado de cada prueba que aplique. Si usted le dice que una 113.698 +prueba falla cuando en realidad era acertada, \emph{podría} detectar 113.699 +la inconsistencia. Si puede identificar una inconsistencia en sus 113.700 +reportes, le dirá que un conjunto de cambios particular es a la vez 113.701 +bueno y malo. Aunque puede no hacerlo; estaría tratando de reportar 113.702 +un conjunto de cambios como el responsable de un fallo aunque no lo 113.703 +sea. 113.704 + 113.705 +\subsection{Automatizar tanto como se pueda} 113.706 + 113.707 +Cuando comencé a usar la orden \hgcmd{bisect}, intenté ejecutar 113.708 +algunas veces las pruebas a mano desde la línea de comandos. Es una 113.709 +aproximación a la cual no esta acostumbrado. Después de algunos 113.710 +intentos, me di cuenta que estaba cometiendo tantas equivocaciones que 113.711 +tenía que comenzar de nuevo con mis búsquedas varias veces antes de 113.712 +llegar a los resultados deseados. 113.713 + 113.714 +Mi problema inicial al dirigir a la orden \hgcmd{bisect} manualmente 113.715 +ocurrieron incluso con búsquedas en repositorios pequeños; si el 113.716 +problema que está buscando es más sutil, o el número de pruebas que 113.717 +\hgcmd{bisect} debe aplicar, la posibilidad de errar es mucho más 113.718 +alta. Una vez que comencé a automatizar mis pruebas, obtuve mejores 113.719 +resultados. 113.720 + 113.721 +La clave para las pruebas automatizadas se puede resumir en: 113.722 +\begin{itemize} 113.723 +\item pruebe siempre buscando el mismo síntoma y 113.724 +\item ofrezca siempre datos consistentes a la orden \hgcmd{bisect}. 113.725 +\end{itemize} 113.726 +En mi tutorial de ejemplo anterior, la orden \command{grep} busca el 113.727 +síntoma, y la construcción \texttt{if} toma el resultado de esta 113.728 +prueba y verifica que siempre alimentamos con los mismos datos a la 113.729 +orden \hgcmd{bisect}. La función \texttt{mytest} los une de una forma 113.730 +reproducible, logrando que cada prueba sea uniforme y consistente. 113.731 + 113.732 +\subsection{Verificar los resultados} 113.733 + 113.734 +Dado que la salida de la búsqueda de \hgcmd{bisect} es tan buena como 113.735 +los datos ofrecidos por usted, no confíe en esto como si fuera la 113.736 +verdad absoluta. Una forma sencilla de asegurarse es ejecutar 113.737 +manualmente su prueba a cada uno de los siguientes conjuntos de 113.738 +cambios: 113.739 +\begin{itemize} 113.740 +\item El conjunto de cambios que se reportó como la primera versión 113.741 + erronea. Su prueba debería dar un reporte de fallo. 113.742 +\item El conjunto de cambios padre (cada padre, si es una fusión). 113.743 + Su prueba debería reportar este(os) conjunto(s) de cambios como 113.744 + bueno(s). 113.745 +\item Un hijo del conjunto de cambios. Su prueba debería reportar al 113.746 + conjunto de cambios hijo como malo. 113.747 +\end{itemize} 113.748 + 113.749 +\subsection{Tener en cuenta la interferencia entre fallos} 113.750 + 113.751 +Es posible que su búsqueda de un fallo pueda viciarse por la presencia 113.752 +de otro. Por ejemplo, digamos que su programa se revienta en la 113.753 +revisión 100, y que funcionó correctamente en la revisión 50. Sin su 113.754 +conocimiento, alguien introdujo un fallo con consecuencias grandes en 113.755 +la revisión 60, y lo arregló en la revisión 80. Sus resultados 113.756 +estarían distorcionados de una o muchas formas. 113.757 + 113.758 +Es posible que este fallo ``enmascare'' completamente al suyo, y que 113.759 +podría haberse revelado antes de que su propio fallo haya tenido 113.760 +oportunidad de manifestarse. Si no puede saltar el otro fallo (por 113.761 +ejemplo, este evita que su proyecto se arme o compile), y de esta 113.762 +forma no se pueda revisar si su fallo esté presente en un conjunto 113.763 +particular de cambios, la orden \hgcmd{bisect} no podrá ayudarle 113.764 +directamente. En cambio, puede marcar este conjunto de cambios como 113.765 +al ejecutar \hgcmdargs{bisect}{--skip}. 113.766 + 113.767 +Un problema distinto podría surgir si su prueba de la presencia de un 113.768 +fallo no es suficientemente específica. Si usted busca ``mi programa 113.769 +se revienta'', entonces tanto su fallo como el otro fallo sin relación 113.770 +que terminan presentando síntomas distintos, podría terminar 113.771 +confundiendo a \hgcmd{bisect}. 113.772 + 113.773 +Otra situación en la cual sería de mucha utilidad emplear a 113.774 +\hgcmdargs{bisect}{--skip} surge cuando usted no puede probar una 113.775 +revisión porque su proyecto estaba en una situación de rompimiento y 113.776 +por lo tanto en un estado en el cual era imposible hacer la prueba en 113.777 +esa revisión, tal vez porque alguien consignó un cambio que hacía 113.778 +imposible la construcción del proyecto. 113.779 + 113.780 +\subsection{Acotar la búsqueda perezosamente} 113.781 + 113.782 +Elegir los primeros ``buenos'' y ``malos'' conjuntos de cambios que 113.783 +marcarán los límites de su búsqueda en general es sencillo, pero vale 113.784 +la pena discutirlo. Desde la perspectiva de \hgcmd{bisect}, el 113.785 +conjunto de cambios ``más nuevo'' por convención es el ``malo'', y el 113.786 +otro conjunto de cambios es el ``bueno''. 113.787 + 113.788 +Si no recuerda cuál podría ser el cambio ``bueno'', para informar a 113.789 +\hgcmd{bisect}, podría hacer pruebas aleatorias en el peor de los 113.790 +casos. Pero recuerde eliminar aquellos conjuntos de cambios que 113.791 +podrían no exhibir el fallo (tal vez porque la característica donde se 113.792 +presenta el fallo todavía no está presente) y aquellos en los cuales 113.793 +otro fallo puede enmascararlo (como se discutió anteriormente). 113.794 + 113.795 +Incluso si termina ``muy atrás'' por miles de conjuntos de cambios o 113.796 +meses de historial, solamente estaŕa adicionando unas pruebas contadas 113.797 +para \hgcmd{bisect}, gracias al comportamiento logarítmico. 113.798 + 113.799 +%%% Local Variables: 113.800 +%%% mode: latex 113.801 +%%% TeX-master: "00book" 113.802 +%%% End:
114.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 114.2 +++ b/es/wdir-after-commit.svg Thu Jan 29 22:00:07 2009 -0800 114.3 @@ -0,0 +1,413 @@ 114.4 +<?xml version="1.0" encoding="UTF-8" standalone="no"?> 114.5 +<!-- Created with Inkscape (http://www.inkscape.org/) --> 114.6 +<svg 114.7 + xmlns:dc="http://purl.org/dc/elements/1.1/" 114.8 + xmlns:cc="http://creativecommons.org/ns#" 114.9 + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 114.10 + xmlns:svg="http://www.w3.org/2000/svg" 114.11 + xmlns="http://www.w3.org/2000/svg" 114.12 + xmlns:xlink="http://www.w3.org/1999/xlink" 114.13 + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" 114.14 + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" 114.15 + width="744.09448819" 114.16 + height="1052.3622047" 114.17 + id="svg5971" 114.18 + sodipodi:version="0.32" 114.19 + inkscape:version="0.46" 114.20 + sodipodi:docbase="/home/bos/hg/hgbook/en" 114.21 + sodipodi:docname="wdir-after-commit.svg" 114.22 + inkscape:output_extension="org.inkscape.output.svg.inkscape"> 114.23 + <defs 114.24 + id="defs5973"> 114.25 + <inkscape:perspective 114.26 + sodipodi:type="inkscape:persp3d" 114.27 + inkscape:vp_x="0 : 526.18109 : 1" 114.28 + inkscape:vp_y="0 : 1000 : 0" 114.29 + inkscape:vp_z="744.09448 : 526.18109 : 1" 114.30 + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" 114.31 + id="perspective3128" /> 114.32 + <linearGradient 114.33 + inkscape:collect="always" 114.34 + xlink:href="#linearGradient6049" 114.35 + id="linearGradient6445" 114.36 + gradientUnits="userSpaceOnUse" 114.37 + gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)" 114.38 + x1="333.91171" 114.39 + y1="488.79077" 114.40 + x2="508.94543" 114.41 + y2="263.79077" /> 114.42 + <marker 114.43 + inkscape:stockid="Arrow1Mstart" 114.44 + orient="auto" 114.45 + refY="0.0" 114.46 + refX="0.0" 114.47 + id="Arrow1Mstart" 114.48 + style="overflow:visible"> 114.49 + <path 114.50 + id="path4855" 114.51 + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " 114.52 + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none" 114.53 + transform="scale(0.4) translate(10,0)" /> 114.54 + </marker> 114.55 + <linearGradient 114.56 + id="linearGradient6049"> 114.57 + <stop 114.58 + style="stop-color:#686868;stop-opacity:1;" 114.59 + offset="0" 114.60 + id="stop6051" /> 114.61 + <stop 114.62 + style="stop-color:#f0f0f0;stop-opacity:1;" 114.63 + offset="1" 114.64 + id="stop6053" /> 114.65 + </linearGradient> 114.66 + <marker 114.67 + inkscape:stockid="Arrow1Mend" 114.68 + orient="auto" 114.69 + refY="0.0" 114.70 + refX="0.0" 114.71 + id="Arrow1Mend" 114.72 + style="overflow:visible;"> 114.73 + <path 114.74 + id="path4852" 114.75 + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " 114.76 + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;" 114.77 + transform="scale(0.4) rotate(180) translate(10,0)" /> 114.78 + </marker> 114.79 + <linearGradient 114.80 + inkscape:collect="always" 114.81 + xlink:href="#linearGradient6049" 114.82 + id="linearGradient6083" 114.83 + gradientUnits="userSpaceOnUse" 114.84 + gradientTransform="translate(-240.0462,-8.633237e-6)" 114.85 + x1="333.91171" 114.86 + y1="488.79077" 114.87 + x2="508.94543" 114.88 + y2="263.79077" /> 114.89 + <linearGradient 114.90 + inkscape:collect="always" 114.91 + xlink:href="#linearGradient6049" 114.92 + id="linearGradient6142" 114.93 + gradientUnits="userSpaceOnUse" 114.94 + gradientTransform="translate(-42.00893,-30.49544)" 114.95 + x1="333.91171" 114.96 + y1="488.79077" 114.97 + x2="508.94543" 114.98 + y2="263.79077" /> 114.99 + <linearGradient 114.100 + inkscape:collect="always" 114.101 + xlink:href="#linearGradient6049" 114.102 + id="linearGradient6193" 114.103 + gradientUnits="userSpaceOnUse" 114.104 + gradientTransform="translate(-240.0462,-8.633237e-6)" 114.105 + x1="333.91171" 114.106 + y1="488.79077" 114.107 + x2="508.94543" 114.108 + y2="263.79077" /> 114.109 + <linearGradient 114.110 + inkscape:collect="always" 114.111 + xlink:href="#linearGradient6049" 114.112 + id="linearGradient6216" 114.113 + gradientUnits="userSpaceOnUse" 114.114 + gradientTransform="translate(-6.0462,-0.664361)" 114.115 + x1="333.91171" 114.116 + y1="488.79077" 114.117 + x2="508.94543" 114.118 + y2="263.79077" /> 114.119 + <linearGradient 114.120 + inkscape:collect="always" 114.121 + xlink:href="#linearGradient6049" 114.122 + id="linearGradient6232" 114.123 + gradientUnits="userSpaceOnUse" 114.124 + gradientTransform="matrix(1.000474,0,0,0.790947,222.8399,50.85693)" 114.125 + x1="333.91171" 114.126 + y1="488.79077" 114.127 + x2="508.94543" 114.128 + y2="263.79077" /> 114.129 + <linearGradient 114.130 + inkscape:collect="always" 114.131 + xlink:href="#linearGradient6049" 114.132 + id="linearGradient6772" 114.133 + gradientUnits="userSpaceOnUse" 114.134 + gradientTransform="matrix(1.000474,0,0,0.790947,222.8399,50.85693)" 114.135 + x1="333.91171" 114.136 + y1="488.79077" 114.137 + x2="508.94543" 114.138 + y2="263.79077" /> 114.139 + </defs> 114.140 + <sodipodi:namedview 114.141 + id="base" 114.142 + pagecolor="#ffffff" 114.143 + bordercolor="#666666" 114.144 + borderopacity="1.0" 114.145 + gridtolerance="10000" 114.146 + guidetolerance="10" 114.147 + objecttolerance="10" 114.148 + inkscape:pageopacity="0.0" 114.149 + inkscape:pageshadow="2" 114.150 + inkscape:zoom="0.90509668" 114.151 + inkscape:cx="390.0539" 114.152 + inkscape:cy="602.10507" 114.153 + inkscape:document-units="px" 114.154 + inkscape:current-layer="layer1" 114.155 + showguides="true" 114.156 + inkscape:guide-bbox="true" 114.157 + inkscape:window-width="906" 114.158 + inkscape:window-height="659" 114.159 + inkscape:window-x="11" 114.160 + inkscape:window-y="8" 114.161 + showgrid="false"> 114.162 + <sodipodi:guide 114.163 + orientation="vertical" 114.164 + position="-1.4285714" 114.165 + id="guide6022" /> 114.166 + </sodipodi:namedview> 114.167 + <metadata 114.168 + id="metadata5976"> 114.169 + <rdf:RDF> 114.170 + <cc:Work 114.171 + rdf:about=""> 114.172 + <dc:format>image/svg+xml</dc:format> 114.173 + <dc:type 114.174 + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> 114.175 + </cc:Work> 114.176 + </rdf:RDF> 114.177 + </metadata> 114.178 + <g 114.179 + inkscape:label="Layer 1" 114.180 + inkscape:groupmode="layer" 114.181 + id="layer1"> 114.182 + <rect 114.183 + y="245.98355" 114.184 + x="328.23956" 114.185 + height="258.57144" 114.186 + width="174.28572" 114.187 + id="rect6047" 114.188 + style="fill:url(#linearGradient6216);fill-opacity:1;stroke:#686868;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> 114.189 + <g 114.190 + id="g6261" 114.191 + transform="translate(234,0)"> 114.192 + <rect 114.193 + y="258.7149" 114.194 + x="114.11369" 114.195 + height="44.537449" 114.196 + width="134.53746" 114.197 + id="rect5983" 114.198 + style="fill:#b1b1b1;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" /> 114.199 + <text 114.200 + id="text5985" 114.201 + y="284.47562" 114.202 + x="138.7962" 114.203 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 114.204 + xml:space="preserve"><tspan 114.205 + style="font-family:Courier" 114.206 + y="284.47562" 114.207 + x="138.7962" 114.208 + id="tspan5987" 114.209 + sodipodi:role="line">dfbbb33f3fa3</tspan></text> 114.210 + </g> 114.211 + <rect 114.212 + style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" 114.213 + id="rect5996" 114.214 + width="134.53746" 114.215 + height="44.537449" 114.216 + x="348.11371" 114.217 + y="320.38159" /> 114.218 + <text 114.219 + xml:space="preserve" 114.220 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 114.221 + x="372.7962" 114.222 + y="346.1423" 114.223 + id="text5998"><tspan 114.224 + sodipodi:role="line" 114.225 + id="tspan6000" 114.226 + x="372.7962" 114.227 + y="346.1423" 114.228 + style="font-family:Courier">e7639888bb2f</tspan></text> 114.229 + <rect 114.230 + style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" 114.231 + id="rect6004" 114.232 + width="134.53746" 114.233 + height="44.537449" 114.234 + x="348.11371" 114.235 + y="382.04825" /> 114.236 + <text 114.237 + xml:space="preserve" 114.238 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 114.239 + x="370.65421" 114.240 + y="407.80896" 114.241 + id="text6006"><tspan 114.242 + sodipodi:role="line" 114.243 + id="tspan6008" 114.244 + x="370.65421" 114.245 + y="407.80896" 114.246 + style="font-family:Courier">7b064d8bac5e</tspan></text> 114.247 + <path 114.248 + inkscape:connector-type="polyline" 114.249 + id="path6018" 114.250 + d="M 415.38242,303.62646 L 415.38242,320.00744" 114.251 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" /> 114.252 + <path 114.253 + inkscape:connection-end="#rect6004" 114.254 + inkscape:connector-type="polyline" 114.255 + id="path6020" 114.256 + d="M 415.38242,365.29315 L 415.38243,381.67412" 114.257 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" /> 114.258 + <rect 114.259 + style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 114.260 + id="rect6039" 114.261 + width="134.53746" 114.262 + height="44.537449" 114.263 + x="348.11359" 114.264 + y="443.71487" /> 114.265 + <text 114.266 + xml:space="preserve" 114.267 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 114.268 + x="372.79706" 114.269 + y="469.47556" 114.270 + id="text6041"><tspan 114.271 + sodipodi:role="line" 114.272 + id="tspan6043" 114.273 + x="372.79706" 114.274 + y="469.47556" 114.275 + style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text> 114.276 + <path 114.277 + inkscape:connection-end="#rect6039" 114.278 + inkscape:connector-type="polyline" 114.279 + id="path6045" 114.280 + d="M 415.38238,426.95981 L 415.38235,443.34087" 114.281 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#686868;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" /> 114.282 + <text 114.283 + xml:space="preserve" 114.284 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 114.285 + x="327.66046" 114.286 + y="231.36218" 114.287 + id="text6102"><tspan 114.288 + sodipodi:role="line" 114.289 + id="tspan6104" 114.290 + x="327.66046" 114.291 + y="231.36218">Historia en el repositorio</tspan></text> 114.292 + <rect 114.293 + y="245.94225" 114.294 + x="557.28418" 114.295 + height="204.51619" 114.296 + width="174.36833" 114.297 + id="rect6140" 114.298 + style="fill:url(#linearGradient6232);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> 114.299 + <g 114.300 + id="g6130" 114.301 + transform="translate(262.3254,24.38544)"> 114.302 + <rect 114.303 + style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" 114.304 + id="rect6106" 114.305 + width="134.53746" 114.306 + height="44.537449" 114.307 + x="314.87415" 114.308 + y="257.95059" /> 114.309 + <text 114.310 + xml:space="preserve" 114.311 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 114.312 + x="339.55664" 114.313 + y="283.7113" 114.314 + id="text6108"><tspan 114.315 + sodipodi:role="line" 114.316 + id="tspan6110" 114.317 + x="339.55664" 114.318 + y="283.7113" 114.319 + style="font-family:Courier">dfbbb33f3fa3</tspan></text> 114.320 + </g> 114.321 + <g 114.322 + id="g6135" 114.323 + transform="translate(263.0396,49.83106)"> 114.324 + <rect 114.325 + inkscape:transform-center-y="102.85714" 114.326 + inkscape:transform-center-x="129.28571" 114.327 + style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 114.328 + id="rect6112" 114.329 + width="134.53746" 114.330 + height="44.537449" 114.331 + x="314.15985" 114.332 + y="326.52203" /> 114.333 + <text 114.334 + inkscape:transform-center-y="102.7311" 114.335 + inkscape:transform-center-x="128.69672" 114.336 + xml:space="preserve" 114.337 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 114.338 + x="338.84335" 114.339 + y="352.28271" 114.340 + id="text6114"><tspan 114.341 + sodipodi:role="line" 114.342 + id="tspan6116" 114.343 + x="338.84335" 114.344 + y="352.28271" 114.345 + style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text> 114.346 + </g> 114.347 + <text 114.348 + xml:space="preserve" 114.349 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 114.350 + x="576.63208" 114.351 + y="270.479" 114.352 + id="text6118"><tspan 114.353 + sodipodi:role="line" 114.354 + id="tspan6120" 114.355 + x="576.63208" 114.356 + y="270.479">Primer padre</tspan></text> 114.357 + <text 114.358 + xml:space="preserve" 114.359 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 114.360 + x="576.07544" 114.361 + y="364.49615" 114.362 + id="text6122"><tspan 114.363 + sodipodi:role="line" 114.364 + id="tspan6124" 114.365 + x="576.07544" 114.366 + y="364.49615">Segundo padre</tspan></text> 114.367 + <text 114.368 + xml:space="preserve" 114.369 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 114.370 + x="556.61743" 114.371 + y="231.36218" 114.372 + id="text6195"><tspan 114.373 + sodipodi:role="line" 114.374 + id="tspan6197" 114.375 + x="556.61743" 114.376 + y="231.36218">Padres del directorio de trabajo</tspan></text> 114.377 + <path 114.378 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" 114.379 + d="M 576.82542,297.63008 L 483.02528,287.95831" 114.380 + id="path6266" 114.381 + inkscape:connector-type="polyline" 114.382 + inkscape:connection-start="#g6130" 114.383 + inkscape:connection-end="#g6261" /> 114.384 + <path 114.385 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" 114.386 + d="M 665.12232,418.17579 L 665.12232,418.17579" 114.387 + id="path6270" 114.388 + inkscape:connector-type="polyline" /> 114.389 + <text 114.390 + xml:space="preserve" 114.391 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 114.392 + x="316.86407" 114.393 + y="275.6496" 114.394 + id="text6573"><tspan 114.395 + sodipodi:role="line" 114.396 + id="tspan6575" 114.397 + x="316.86407" 114.398 + y="275.6496" 114.399 + style="text-align:end;text-anchor:end">Nuevo</tspan><tspan 114.400 + sodipodi:role="line" 114.401 + x="316.86407" 114.402 + y="290.6496" 114.403 + id="tspan6577" 114.404 + style="text-align:end;text-anchor:end">conjunto</tspan><tspan 114.405 + sodipodi:role="line" 114.406 + x="316.86407" 114.407 + y="305.6496" 114.408 + style="text-align:end;text-anchor:end" 114.409 + id="tspan3470">de</tspan><tspan 114.410 + sodipodi:role="line" 114.411 + x="316.86407" 114.412 + y="320.6496" 114.413 + style="text-align:end;text-anchor:end" 114.414 + id="tspan3472">cambios</tspan></text> 114.415 + </g> 114.416 +</svg>
115.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 115.2 +++ b/es/wdir-branch.svg Thu Jan 29 22:00:07 2009 -0800 115.3 @@ -0,0 +1,427 @@ 115.4 +<?xml version="1.0" encoding="UTF-8" standalone="no"?> 115.5 +<!-- Created with Inkscape (http://www.inkscape.org/) --> 115.6 +<svg 115.7 + xmlns:dc="http://purl.org/dc/elements/1.1/" 115.8 + xmlns:cc="http://creativecommons.org/ns#" 115.9 + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 115.10 + xmlns:svg="http://www.w3.org/2000/svg" 115.11 + xmlns="http://www.w3.org/2000/svg" 115.12 + xmlns:xlink="http://www.w3.org/1999/xlink" 115.13 + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" 115.14 + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" 115.15 + width="744.09448819" 115.16 + height="1052.3622047" 115.17 + id="svg5971" 115.18 + sodipodi:version="0.32" 115.19 + inkscape:version="0.46" 115.20 + sodipodi:docbase="/home/bos/hg/hgbook/en" 115.21 + sodipodi:docname="wdir-branch.svg" 115.22 + inkscape:output_extension="org.inkscape.output.svg.inkscape"> 115.23 + <defs 115.24 + id="defs5973"> 115.25 + <inkscape:perspective 115.26 + sodipodi:type="inkscape:persp3d" 115.27 + inkscape:vp_x="0 : 526.18109 : 1" 115.28 + inkscape:vp_y="0 : 1000 : 0" 115.29 + inkscape:vp_z="744.09448 : 526.18109 : 1" 115.30 + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" 115.31 + id="perspective3193" /> 115.32 + <marker 115.33 + inkscape:stockid="Arrow1Mstart" 115.34 + orient="auto" 115.35 + refY="0.0" 115.36 + refX="0.0" 115.37 + id="Arrow1Mstart" 115.38 + style="overflow:visible"> 115.39 + <path 115.40 + id="path4855" 115.41 + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " 115.42 + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none" 115.43 + transform="scale(0.4) translate(10,0)" /> 115.44 + </marker> 115.45 + <linearGradient 115.46 + id="linearGradient6049"> 115.47 + <stop 115.48 + style="stop-color:#686868;stop-opacity:1;" 115.49 + offset="0" 115.50 + id="stop6051" /> 115.51 + <stop 115.52 + style="stop-color:#f0f0f0;stop-opacity:1;" 115.53 + offset="1" 115.54 + id="stop6053" /> 115.55 + </linearGradient> 115.56 + <marker 115.57 + inkscape:stockid="Arrow1Mend" 115.58 + orient="auto" 115.59 + refY="0.0" 115.60 + refX="0.0" 115.61 + id="Arrow1Mend" 115.62 + style="overflow:visible;"> 115.63 + <path 115.64 + id="path4852" 115.65 + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " 115.66 + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;" 115.67 + transform="scale(0.4) rotate(180) translate(10,0)" /> 115.68 + </marker> 115.69 + <linearGradient 115.70 + inkscape:collect="always" 115.71 + xlink:href="#linearGradient6049" 115.72 + id="linearGradient6083" 115.73 + gradientUnits="userSpaceOnUse" 115.74 + gradientTransform="translate(-240.0462,-8.633237e-6)" 115.75 + x1="333.91171" 115.76 + y1="488.79077" 115.77 + x2="508.94543" 115.78 + y2="263.79077" /> 115.79 + <linearGradient 115.80 + inkscape:collect="always" 115.81 + xlink:href="#linearGradient6049" 115.82 + id="linearGradient6142" 115.83 + gradientUnits="userSpaceOnUse" 115.84 + gradientTransform="translate(-42.00893,-30.49544)" 115.85 + x1="333.91171" 115.86 + y1="488.79077" 115.87 + x2="508.94543" 115.88 + y2="263.79077" /> 115.89 + <linearGradient 115.90 + inkscape:collect="always" 115.91 + xlink:href="#linearGradient6049" 115.92 + id="linearGradient6193" 115.93 + gradientUnits="userSpaceOnUse" 115.94 + gradientTransform="translate(-240.0462,-8.633237e-6)" 115.95 + x1="333.91171" 115.96 + y1="488.79077" 115.97 + x2="508.94543" 115.98 + y2="263.79077" /> 115.99 + <linearGradient 115.100 + inkscape:collect="always" 115.101 + xlink:href="#linearGradient6049" 115.102 + id="linearGradient6216" 115.103 + gradientUnits="userSpaceOnUse" 115.104 + gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)" 115.105 + x1="333.91171" 115.106 + y1="488.79077" 115.107 + x2="508.94543" 115.108 + y2="263.79077" /> 115.109 + <linearGradient 115.110 + inkscape:collect="always" 115.111 + xlink:href="#linearGradient6049" 115.112 + id="linearGradient6232" 115.113 + gradientUnits="userSpaceOnUse" 115.114 + gradientTransform="matrix(1.000473,0,0,0.790947,-11.16012,50.85693)" 115.115 + x1="333.91171" 115.116 + y1="488.79077" 115.117 + x2="508.94543" 115.118 + y2="263.79077" /> 115.119 + <linearGradient 115.120 + inkscape:collect="always" 115.121 + xlink:href="#linearGradient6049" 115.122 + id="linearGradient6445" 115.123 + gradientUnits="userSpaceOnUse" 115.124 + gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)" 115.125 + x1="333.91171" 115.126 + y1="488.79077" 115.127 + x2="508.94543" 115.128 + y2="263.79077" /> 115.129 + <linearGradient 115.130 + inkscape:collect="always" 115.131 + xlink:href="#linearGradient6049" 115.132 + id="linearGradient6974" 115.133 + gradientUnits="userSpaceOnUse" 115.134 + gradientTransform="matrix(1.911882,0,0,0.789965,-574.7896,51.22599)" 115.135 + x1="333.91171" 115.136 + y1="488.79077" 115.137 + x2="508.94543" 115.138 + y2="263.79077" /> 115.139 + <linearGradient 115.140 + inkscape:collect="always" 115.141 + xlink:href="#linearGradient6049" 115.142 + id="linearGradient6996" 115.143 + gradientUnits="userSpaceOnUse" 115.144 + gradientTransform="matrix(1.000473,0,0,0.790947,112.8399,50.85693)" 115.145 + x1="333.91171" 115.146 + y1="488.79077" 115.147 + x2="508.94543" 115.148 + y2="263.79077" /> 115.149 + </defs> 115.150 + <sodipodi:namedview 115.151 + id="base" 115.152 + pagecolor="#ffffff" 115.153 + bordercolor="#666666" 115.154 + borderopacity="1.0" 115.155 + gridtolerance="10000" 115.156 + guidetolerance="10" 115.157 + objecttolerance="10" 115.158 + inkscape:pageopacity="0.0" 115.159 + inkscape:pageshadow="2" 115.160 + inkscape:zoom="0.90509668" 115.161 + inkscape:cx="345.85973" 115.162 + inkscape:cy="690.49342" 115.163 + inkscape:document-units="px" 115.164 + inkscape:current-layer="layer1" 115.165 + showguides="true" 115.166 + inkscape:guide-bbox="true" 115.167 + inkscape:window-width="906" 115.168 + inkscape:window-height="659" 115.169 + inkscape:window-x="75" 115.170 + inkscape:window-y="69" 115.171 + showgrid="false"> 115.172 + <sodipodi:guide 115.173 + orientation="vertical" 115.174 + position="-1.4285714" 115.175 + id="guide6022" /> 115.176 + </sodipodi:namedview> 115.177 + <metadata 115.178 + id="metadata5976"> 115.179 + <rdf:RDF> 115.180 + <cc:Work 115.181 + rdf:about=""> 115.182 + <dc:format>image/svg+xml</dc:format> 115.183 + <dc:type 115.184 + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> 115.185 + </cc:Work> 115.186 + </rdf:RDF> 115.187 + </metadata> 115.188 + <g 115.189 + inkscape:label="Layer 1" 115.190 + inkscape:groupmode="layer" 115.191 + id="layer1"> 115.192 + <rect 115.193 + y="246.06918" 115.194 + x="64.325172" 115.195 + height="204.26233" 115.196 + width="333.2135" 115.197 + id="rect6047" 115.198 + style="fill:url(#linearGradient6974);fill-opacity:1;stroke:#686868;stroke-width:0.91925466;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> 115.199 + <g 115.200 + id="g1935"> 115.201 + <rect 115.202 + y="266.24374" 115.203 + x="84.113708" 115.204 + height="44.537449" 115.205 + width="134.53746" 115.206 + id="rect5996" 115.207 + style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" /> 115.208 + <text 115.209 + id="text5998" 115.210 + y="292.00446" 115.211 + x="108.7962" 115.212 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 115.213 + xml:space="preserve"><tspan 115.214 + style="font-family:Courier" 115.215 + y="292.00446" 115.216 + x="108.7962" 115.217 + id="tspan6000" 115.218 + sodipodi:role="line">e7639888bb2f</tspan></text> 115.219 + </g> 115.220 + <g 115.221 + id="g6976" 115.222 + transform="translate(70,0)"> 115.223 + <rect 115.224 + y="327.9104" 115.225 + x="40.113693" 115.226 + height="44.537449" 115.227 + width="134.53746" 115.228 + id="rect6004" 115.229 + style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" /> 115.230 + <text 115.231 + id="text6006" 115.232 + y="353.67111" 115.233 + x="62.654205" 115.234 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 115.235 + xml:space="preserve"><tspan 115.236 + style="font-family:Courier" 115.237 + y="353.67111" 115.238 + x="62.654205" 115.239 + id="tspan6008" 115.240 + sodipodi:role="line">7b064d8bac5e</tspan></text> 115.241 + </g> 115.242 + <path 115.243 + inkscape:connector-type="polyline" 115.244 + id="path6020" 115.245 + d="M 160.92915,311.15532 L 167.83571,327.53627" 115.246 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline" 115.247 + inkscape:connection-end="#g6976" 115.248 + inkscape:connection-start="#g1935" /> 115.249 + <rect 115.250 + style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 115.251 + id="rect6039" 115.252 + width="134.53746" 115.253 + height="44.537449" 115.254 + x="110.11359" 115.255 + y="389.57703" /> 115.256 + <text 115.257 + xml:space="preserve" 115.258 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 115.259 + x="134.79706" 115.260 + y="415.33771" 115.261 + id="text6041"><tspan 115.262 + sodipodi:role="line" 115.263 + id="tspan6043" 115.264 + x="134.79706" 115.265 + y="415.33771" 115.266 + style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text> 115.267 + <path 115.268 + inkscape:connection-end="#rect6039" 115.269 + inkscape:connector-type="polyline" 115.270 + id="path6045" 115.271 + d="M 177.38238,372.82195 L 177.38235,389.20303" 115.272 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#686868;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" /> 115.273 + <rect 115.274 + y="245.94225" 115.275 + x="447.28412" 115.276 + height="204.51619" 115.277 + width="174.36833" 115.278 + id="rect6140" 115.279 + style="fill:url(#linearGradient6996);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> 115.280 + <g 115.281 + id="g6130" 115.282 + transform="translate(152.3254,24.38544)"> 115.283 + <rect 115.284 + style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" 115.285 + id="rect6106" 115.286 + width="134.53746" 115.287 + height="44.537449" 115.288 + x="314.87415" 115.289 + y="257.95059" /> 115.290 + <text 115.291 + xml:space="preserve" 115.292 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 115.293 + x="339.55664" 115.294 + y="283.7113" 115.295 + id="text6108"><tspan 115.296 + sodipodi:role="line" 115.297 + id="tspan6110" 115.298 + x="339.55664" 115.299 + y="283.7113" 115.300 + style="font-family:Courier">ffb20e1701ea</tspan></text> 115.301 + </g> 115.302 + <g 115.303 + id="g6135" 115.304 + transform="translate(153.0396,49.83106)"> 115.305 + <rect 115.306 + inkscape:transform-center-y="102.85714" 115.307 + inkscape:transform-center-x="129.28571" 115.308 + style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 115.309 + id="rect6112" 115.310 + width="134.53746" 115.311 + height="44.537449" 115.312 + x="314.15985" 115.313 + y="326.52203" /> 115.314 + <text 115.315 + inkscape:transform-center-y="102.7311" 115.316 + inkscape:transform-center-x="128.69672" 115.317 + xml:space="preserve" 115.318 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 115.319 + x="338.84335" 115.320 + y="352.28271" 115.321 + id="text6114"><tspan 115.322 + sodipodi:role="line" 115.323 + id="tspan6116" 115.324 + x="338.84335" 115.325 + y="352.28271" 115.326 + style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text> 115.327 + </g> 115.328 + <text 115.329 + xml:space="preserve" 115.330 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 115.331 + x="466.63208" 115.332 + y="270.479" 115.333 + id="text6118"><tspan 115.334 + sodipodi:role="line" 115.335 + id="tspan6120" 115.336 + x="466.63208" 115.337 + y="270.479">Primer padre</tspan></text> 115.338 + <text 115.339 + xml:space="preserve" 115.340 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 115.341 + x="466.07544" 115.342 + y="364.49615" 115.343 + id="text6122"><tspan 115.344 + sodipodi:role="line" 115.345 + id="tspan6124" 115.346 + x="466.07544" 115.347 + y="364.49615">Segundo padre</tspan></text> 115.348 + <text 115.349 + xml:space="preserve" 115.350 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 115.351 + x="446.61743" 115.352 + y="231.36218" 115.353 + id="text6195"><tspan 115.354 + sodipodi:role="line" 115.355 + id="tspan6197" 115.356 + x="446.61743" 115.357 + y="231.36218">Padres del directorio de trabajo</tspan></text> 115.358 + <path 115.359 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline" 115.360 + d="M 466.82542,300.21999 L 377.00207,294.39744" 115.361 + id="path6266" 115.362 + inkscape:connector-type="polyline" 115.363 + inkscape:connection-start="#g6130" 115.364 + inkscape:connection-end="#rect1925" /> 115.365 + <path 115.366 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" 115.367 + d="M 665.12232,418.17579 L 665.12232,418.17579" 115.368 + id="path6270" 115.369 + inkscape:connector-type="polyline" /> 115.370 + <g 115.371 + id="g2845"> 115.372 + <rect 115.373 + y="266.24374" 115.374 + x="242.09048" 115.375 + height="44.537449" 115.376 + width="134.53746" 115.377 + id="rect1925" 115.378 + style="fill:#9f9f9f;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" /> 115.379 + <text 115.380 + id="text1927" 115.381 + y="292.00446" 115.382 + x="266.77298" 115.383 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 115.384 + xml:space="preserve"><tspan 115.385 + style="font-family:Courier" 115.386 + y="292.00446" 115.387 + x="266.77298" 115.388 + id="tspan1929" 115.389 + sodipodi:role="line">ffb20e1701ea</tspan></text> 115.390 + </g> 115.391 + <path 115.392 + inkscape:connector-type="polyline" 115.393 + id="path1933" 115.394 + d="M 260.89978,311.15532 L 225.84185,327.53627" 115.395 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline" 115.396 + inkscape:connection-end="#g6976" /> 115.397 + <text 115.398 + xml:space="preserve" 115.399 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 115.400 + x="109.45568" 115.401 + y="231.4554" 115.402 + id="text2837"><tspan 115.403 + sodipodi:role="line" 115.404 + id="tspan2839" 115.405 + x="109.45568" 115.406 + y="231.4554">Cabeza Pre-existente</tspan></text> 115.407 + <text 115.408 + xml:space="preserve" 115.409 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 115.410 + x="237.54184" 115.411 + y="231.4554" 115.412 + id="text2841"><tspan 115.413 + sodipodi:role="line" 115.414 + id="tspan2843" 115.415 + x="237.54184" 115.416 + y="231.4554">Cabeza recién creada (y tip)</tspan></text> 115.417 + <path 115.418 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)" 115.419 + d="M 148.05048,235.87482 L 149.94915,265.86962" 115.420 + id="path2850" 115.421 + inkscape:connector-type="polyline" 115.422 + inkscape:connection-end="#g1935" /> 115.423 + <path 115.424 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)" 115.425 + d="M 303.83495,238.08453 L 306.87874,265.86962" 115.426 + id="path2852" 115.427 + inkscape:connector-type="polyline" 115.428 + inkscape:connection-end="#g2845" /> 115.429 + </g> 115.430 +</svg>
116.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 116.2 +++ b/es/wdir-merge.svg Thu Jan 29 22:00:07 2009 -0800 116.3 @@ -0,0 +1,434 @@ 116.4 +<?xml version="1.0" encoding="UTF-8" standalone="no"?> 116.5 +<!-- Created with Inkscape (http://www.inkscape.org/) --> 116.6 +<svg 116.7 + xmlns:dc="http://purl.org/dc/elements/1.1/" 116.8 + xmlns:cc="http://creativecommons.org/ns#" 116.9 + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 116.10 + xmlns:svg="http://www.w3.org/2000/svg" 116.11 + xmlns="http://www.w3.org/2000/svg" 116.12 + xmlns:xlink="http://www.w3.org/1999/xlink" 116.13 + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" 116.14 + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" 116.15 + width="744.09448819" 116.16 + height="1052.3622047" 116.17 + id="svg5971" 116.18 + sodipodi:version="0.32" 116.19 + inkscape:version="0.46" 116.20 + sodipodi:docbase="/home/bos/hg/hgbook/en" 116.21 + sodipodi:docname="wdir-merge.svg" 116.22 + inkscape:output_extension="org.inkscape.output.svg.inkscape"> 116.23 + <defs 116.24 + id="defs5973"> 116.25 + <inkscape:perspective 116.26 + sodipodi:type="inkscape:persp3d" 116.27 + inkscape:vp_x="0 : 526.18109 : 1" 116.28 + inkscape:vp_y="0 : 1000 : 0" 116.29 + inkscape:vp_z="744.09448 : 526.18109 : 1" 116.30 + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" 116.31 + id="perspective3259" /> 116.32 + <marker 116.33 + inkscape:stockid="Arrow1Mstart" 116.34 + orient="auto" 116.35 + refY="0.0" 116.36 + refX="0.0" 116.37 + id="Arrow1Mstart" 116.38 + style="overflow:visible"> 116.39 + <path 116.40 + id="path4855" 116.41 + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " 116.42 + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none" 116.43 + transform="scale(0.4) translate(10,0)" /> 116.44 + </marker> 116.45 + <linearGradient 116.46 + id="linearGradient6049"> 116.47 + <stop 116.48 + style="stop-color:#686868;stop-opacity:1;" 116.49 + offset="0" 116.50 + id="stop6051" /> 116.51 + <stop 116.52 + style="stop-color:#f0f0f0;stop-opacity:1;" 116.53 + offset="1" 116.54 + id="stop6053" /> 116.55 + </linearGradient> 116.56 + <marker 116.57 + inkscape:stockid="Arrow1Mend" 116.58 + orient="auto" 116.59 + refY="0.0" 116.60 + refX="0.0" 116.61 + id="Arrow1Mend" 116.62 + style="overflow:visible;"> 116.63 + <path 116.64 + id="path4852" 116.65 + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " 116.66 + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;" 116.67 + transform="scale(0.4) rotate(180) translate(10,0)" /> 116.68 + </marker> 116.69 + <linearGradient 116.70 + inkscape:collect="always" 116.71 + xlink:href="#linearGradient6049" 116.72 + id="linearGradient6083" 116.73 + gradientUnits="userSpaceOnUse" 116.74 + gradientTransform="translate(-240.0462,-8.633237e-6)" 116.75 + x1="333.91171" 116.76 + y1="488.79077" 116.77 + x2="508.94543" 116.78 + y2="263.79077" /> 116.79 + <linearGradient 116.80 + inkscape:collect="always" 116.81 + xlink:href="#linearGradient6049" 116.82 + id="linearGradient6142" 116.83 + gradientUnits="userSpaceOnUse" 116.84 + gradientTransform="translate(-42.00893,-30.49544)" 116.85 + x1="333.91171" 116.86 + y1="488.79077" 116.87 + x2="508.94543" 116.88 + y2="263.79077" /> 116.89 + <linearGradient 116.90 + inkscape:collect="always" 116.91 + xlink:href="#linearGradient6049" 116.92 + id="linearGradient6193" 116.93 + gradientUnits="userSpaceOnUse" 116.94 + gradientTransform="translate(-240.0462,-8.633237e-6)" 116.95 + x1="333.91171" 116.96 + y1="488.79077" 116.97 + x2="508.94543" 116.98 + y2="263.79077" /> 116.99 + <linearGradient 116.100 + inkscape:collect="always" 116.101 + xlink:href="#linearGradient6049" 116.102 + id="linearGradient6216" 116.103 + gradientUnits="userSpaceOnUse" 116.104 + gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)" 116.105 + x1="333.91171" 116.106 + y1="488.79077" 116.107 + x2="508.94543" 116.108 + y2="263.79077" /> 116.109 + <linearGradient 116.110 + inkscape:collect="always" 116.111 + xlink:href="#linearGradient6049" 116.112 + id="linearGradient6232" 116.113 + gradientUnits="userSpaceOnUse" 116.114 + gradientTransform="matrix(1.000473,0,0,0.790947,-11.16012,50.85693)" 116.115 + x1="333.91171" 116.116 + y1="488.79077" 116.117 + x2="508.94543" 116.118 + y2="263.79077" /> 116.119 + <linearGradient 116.120 + inkscape:collect="always" 116.121 + xlink:href="#linearGradient6049" 116.122 + id="linearGradient6445" 116.123 + gradientUnits="userSpaceOnUse" 116.124 + gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)" 116.125 + x1="333.91171" 116.126 + y1="488.79077" 116.127 + x2="508.94543" 116.128 + y2="263.79077" /> 116.129 + <linearGradient 116.130 + inkscape:collect="always" 116.131 + xlink:href="#linearGradient6049" 116.132 + id="linearGradient6974" 116.133 + gradientUnits="userSpaceOnUse" 116.134 + gradientTransform="matrix(1.911882,0,0,0.789965,-574.7896,51.22599)" 116.135 + x1="333.91171" 116.136 + y1="488.79077" 116.137 + x2="508.94543" 116.138 + y2="263.79077" /> 116.139 + <linearGradient 116.140 + inkscape:collect="always" 116.141 + xlink:href="#linearGradient6049" 116.142 + id="linearGradient6996" 116.143 + gradientUnits="userSpaceOnUse" 116.144 + gradientTransform="matrix(1.000473,0,0,0.790947,112.8399,50.85693)" 116.145 + x1="333.91171" 116.146 + y1="488.79077" 116.147 + x2="508.94543" 116.148 + y2="263.79077" /> 116.149 + </defs> 116.150 + <sodipodi:namedview 116.151 + id="base" 116.152 + pagecolor="#ffffff" 116.153 + bordercolor="#666666" 116.154 + borderopacity="1.0" 116.155 + gridtolerance="10000" 116.156 + guidetolerance="10" 116.157 + objecttolerance="10" 116.158 + inkscape:pageopacity="0.0" 116.159 + inkscape:pageshadow="2" 116.160 + inkscape:zoom="1.28" 116.161 + inkscape:cx="345.85973" 116.162 + inkscape:cy="690.49342" 116.163 + inkscape:document-units="px" 116.164 + inkscape:current-layer="layer1" 116.165 + showguides="true" 116.166 + inkscape:guide-bbox="true" 116.167 + inkscape:window-width="906" 116.168 + inkscape:window-height="659" 116.169 + inkscape:window-x="338" 116.170 + inkscape:window-y="50" 116.171 + showgrid="false"> 116.172 + <sodipodi:guide 116.173 + orientation="vertical" 116.174 + position="-1.4285714" 116.175 + id="guide6022" /> 116.176 + </sodipodi:namedview> 116.177 + <metadata 116.178 + id="metadata5976"> 116.179 + <rdf:RDF> 116.180 + <cc:Work 116.181 + rdf:about=""> 116.182 + <dc:format>image/svg+xml</dc:format> 116.183 + <dc:type 116.184 + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> 116.185 + </cc:Work> 116.186 + </rdf:RDF> 116.187 + </metadata> 116.188 + <g 116.189 + inkscape:label="Layer 1" 116.190 + inkscape:groupmode="layer" 116.191 + id="layer1"> 116.192 + <rect 116.193 + y="246.06918" 116.194 + x="64.325172" 116.195 + height="204.26233" 116.196 + width="333.2135" 116.197 + id="rect6047" 116.198 + style="fill:url(#linearGradient6974);fill-opacity:1;stroke:#686868;stroke-width:0.91925466;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> 116.199 + <g 116.200 + id="g6976" 116.201 + transform="translate(70,0)"> 116.202 + <rect 116.203 + y="327.9104" 116.204 + x="40.113693" 116.205 + height="44.537449" 116.206 + width="134.53746" 116.207 + id="rect6004" 116.208 + style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" /> 116.209 + <text 116.210 + id="text6006" 116.211 + y="353.67111" 116.212 + x="62.654205" 116.213 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 116.214 + xml:space="preserve"><tspan 116.215 + style="font-family:Courier" 116.216 + y="353.67111" 116.217 + x="62.654205" 116.218 + id="tspan6008" 116.219 + sodipodi:role="line">7b064d8bac5e</tspan></text> 116.220 + </g> 116.221 + <path 116.222 + inkscape:connector-type="polyline" 116.223 + id="path6020" 116.224 + d="M 160.92915,311.15532 L 167.83571,327.53627" 116.225 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline" 116.226 + inkscape:connection-end="#g6976" 116.227 + inkscape:connection-start="#g1935" /> 116.228 + <rect 116.229 + style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 116.230 + id="rect6039" 116.231 + width="134.53746" 116.232 + height="44.537449" 116.233 + x="110.11359" 116.234 + y="389.57703" /> 116.235 + <text 116.236 + xml:space="preserve" 116.237 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 116.238 + x="134.79706" 116.239 + y="415.33771" 116.240 + id="text6041"><tspan 116.241 + sodipodi:role="line" 116.242 + id="tspan6043" 116.243 + x="134.79706" 116.244 + y="415.33771" 116.245 + style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text> 116.246 + <path 116.247 + inkscape:connection-end="#rect6039" 116.248 + inkscape:connector-type="polyline" 116.249 + id="path6045" 116.250 + d="M 177.38238,372.82195 L 177.38235,389.20303" 116.251 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#686868;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" /> 116.252 + <rect 116.253 + y="245.94225" 116.254 + x="447.28412" 116.255 + height="204.51619" 116.256 + width="174.36833" 116.257 + id="rect6140" 116.258 + style="fill:url(#linearGradient6996);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> 116.259 + <g 116.260 + id="g6130" 116.261 + transform="translate(152.3254,24.38544)"> 116.262 + <rect 116.263 + style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" 116.264 + id="rect6106" 116.265 + width="134.53746" 116.266 + height="44.537449" 116.267 + x="314.87415" 116.268 + y="257.95059" /> 116.269 + <text 116.270 + xml:space="preserve" 116.271 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 116.272 + x="339.55664" 116.273 + y="283.7113" 116.274 + id="text6108"><tspan 116.275 + sodipodi:role="line" 116.276 + id="tspan6110" 116.277 + x="339.55664" 116.278 + y="283.7113" 116.279 + style="font-family:Courier">ffb20e1701ea</tspan></text> 116.280 + </g> 116.281 + <g 116.282 + id="g6135" 116.283 + transform="translate(153.0396,49.83106)"> 116.284 + <rect 116.285 + inkscape:transform-center-y="102.85714" 116.286 + inkscape:transform-center-x="129.28571" 116.287 + style="fill:#d4d4d4;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 116.288 + id="rect6112" 116.289 + width="134.53746" 116.290 + height="44.537449" 116.291 + x="314.15985" 116.292 + y="326.52203" /> 116.293 + <text 116.294 + inkscape:transform-center-y="102.7311" 116.295 + inkscape:transform-center-x="128.69672" 116.296 + xml:space="preserve" 116.297 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 116.298 + x="338.84335" 116.299 + y="352.28271" 116.300 + id="text6114"><tspan 116.301 + sodipodi:role="line" 116.302 + id="tspan6116" 116.303 + x="338.84335" 116.304 + y="352.28271" 116.305 + style="fill:black;fill-opacity:1;font-family:Courier">e7639888bb2f</tspan></text> 116.306 + </g> 116.307 + <text 116.308 + xml:space="preserve" 116.309 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 116.310 + x="466.63208" 116.311 + y="270.479" 116.312 + id="text6118"><tspan 116.313 + sodipodi:role="line" 116.314 + id="tspan6120" 116.315 + x="466.63208" 116.316 + y="270.479">Primer padre (sin cambio)</tspan></text> 116.317 + <text 116.318 + xml:space="preserve" 116.319 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 116.320 + x="466.07544" 116.321 + y="364.49615" 116.322 + id="text6122"><tspan 116.323 + sodipodi:role="line" 116.324 + id="tspan6124" 116.325 + x="466.07544" 116.326 + y="364.49615">Segundo padre</tspan></text> 116.327 + <text 116.328 + xml:space="preserve" 116.329 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 116.330 + x="446.61743" 116.331 + y="231.36218" 116.332 + id="text6195"><tspan 116.333 + sodipodi:role="line" 116.334 + id="tspan6197" 116.335 + x="446.61743" 116.336 + y="231.36218">Padres del directorio de trabajo</tspan></text> 116.337 + <path 116.338 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline" 116.339 + d="M 466.82542,300.21999 L 377.00207,294.39744" 116.340 + id="path6266" 116.341 + inkscape:connector-type="polyline" 116.342 + inkscape:connection-start="#g6130" 116.343 + inkscape:connection-end="#rect1925" /> 116.344 + <path 116.345 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" 116.346 + d="M 665.12232,418.17579 L 665.12232,418.17579" 116.347 + id="path6270" 116.348 + inkscape:connector-type="polyline" /> 116.349 + <g 116.350 + id="g2845"> 116.351 + <rect 116.352 + y="266.24374" 116.353 + x="242.09048" 116.354 + height="44.537449" 116.355 + width="134.53746" 116.356 + id="rect1925" 116.357 + style="fill:#9f9f9f;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" /> 116.358 + <text 116.359 + id="text1927" 116.360 + y="292.00446" 116.361 + x="266.77298" 116.362 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 116.363 + xml:space="preserve"><tspan 116.364 + style="font-family:Courier" 116.365 + y="292.00446" 116.366 + x="266.77298" 116.367 + id="tspan1929" 116.368 + sodipodi:role="line">ffb20e1701ea</tspan></text> 116.369 + </g> 116.370 + <path 116.371 + inkscape:connector-type="polyline" 116.372 + id="path1933" 116.373 + d="M 260.89978,311.15532 L 225.84185,327.53627" 116.374 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline" 116.375 + inkscape:connection-end="#g6976" /> 116.376 + <text 116.377 + xml:space="preserve" 116.378 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 116.379 + x="109.45568" 116.380 + y="231.4554" 116.381 + id="text2837"><tspan 116.382 + sodipodi:role="line" 116.383 + id="tspan2839" 116.384 + x="109.45568" 116.385 + y="231.4554">Cabeza pre-existente</tspan></text> 116.386 + <text 116.387 + xml:space="preserve" 116.388 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 116.389 + x="237.54184" 116.390 + y="231.4554" 116.391 + id="text2841"><tspan 116.392 + sodipodi:role="line" 116.393 + id="tspan2843" 116.394 + x="237.54184" 116.395 + y="231.4554">Cabeza recién creada(y tip)</tspan></text> 116.396 + <path 116.397 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)" 116.398 + d="M 148.05048,235.87482 L 149.94915,265.86962" 116.399 + id="path2850" 116.400 + inkscape:connector-type="polyline" 116.401 + inkscape:connection-end="#g1935" /> 116.402 + <path 116.403 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)" 116.404 + d="M 303.83495,238.08453 L 306.87874,265.86962" 116.405 + id="path2852" 116.406 + inkscape:connector-type="polyline" 116.407 + inkscape:connection-end="#g2845" /> 116.408 + <path 116.409 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline" 116.410 + d="M 466.82545,379.17944 L 219.0253,307.95488" 116.411 + id="path3016" 116.412 + inkscape:connector-type="polyline" 116.413 + inkscape:connection-start="#g6135" 116.414 + inkscape:connection-end="#g1935" /> 116.415 + <g 116.416 + id="g1935"> 116.417 + <rect 116.418 + y="266.24374" 116.419 + x="84.113708" 116.420 + height="44.537449" 116.421 + width="134.53746" 116.422 + id="rect5996" 116.423 + style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" /> 116.424 + <text 116.425 + id="text5998" 116.426 + y="292.00446" 116.427 + x="108.7962" 116.428 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 116.429 + xml:space="preserve"><tspan 116.430 + style="font-family:Courier" 116.431 + y="292.00446" 116.432 + x="108.7962" 116.433 + id="tspan6000" 116.434 + sodipodi:role="line">e7639888bb2f</tspan></text> 116.435 + </g> 116.436 + </g> 116.437 +</svg>
117.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 117.2 +++ b/es/wdir-pre-branch.svg Thu Jan 29 22:00:07 2009 -0800 117.3 @@ -0,0 +1,373 @@ 117.4 +<?xml version="1.0" encoding="UTF-8" standalone="no"?> 117.5 +<!-- Created with Inkscape (http://www.inkscape.org/) --> 117.6 +<svg 117.7 + xmlns:dc="http://purl.org/dc/elements/1.1/" 117.8 + xmlns:cc="http://creativecommons.org/ns#" 117.9 + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 117.10 + xmlns:svg="http://www.w3.org/2000/svg" 117.11 + xmlns="http://www.w3.org/2000/svg" 117.12 + xmlns:xlink="http://www.w3.org/1999/xlink" 117.13 + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" 117.14 + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" 117.15 + width="744.09448819" 117.16 + height="1052.3622047" 117.17 + id="svg5971" 117.18 + sodipodi:version="0.32" 117.19 + inkscape:version="0.46" 117.20 + sodipodi:docbase="/home/bos/hg/hgbook/en" 117.21 + sodipodi:docname="wdir-pre-branch.svg" 117.22 + inkscape:output_extension="org.inkscape.output.svg.inkscape"> 117.23 + <defs 117.24 + id="defs5973"> 117.25 + <inkscape:perspective 117.26 + sodipodi:type="inkscape:persp3d" 117.27 + inkscape:vp_x="0 : 526.18109 : 1" 117.28 + inkscape:vp_y="0 : 1000 : 0" 117.29 + inkscape:vp_z="744.09448 : 526.18109 : 1" 117.30 + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" 117.31 + id="perspective3314" /> 117.32 + <marker 117.33 + inkscape:stockid="Arrow1Mstart" 117.34 + orient="auto" 117.35 + refY="0.0" 117.36 + refX="0.0" 117.37 + id="Arrow1Mstart" 117.38 + style="overflow:visible"> 117.39 + <path 117.40 + id="path4855" 117.41 + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " 117.42 + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none" 117.43 + transform="scale(0.4) translate(10,0)" /> 117.44 + </marker> 117.45 + <linearGradient 117.46 + id="linearGradient6049"> 117.47 + <stop 117.48 + style="stop-color:#686868;stop-opacity:1;" 117.49 + offset="0" 117.50 + id="stop6051" /> 117.51 + <stop 117.52 + style="stop-color:#f0f0f0;stop-opacity:1;" 117.53 + offset="1" 117.54 + id="stop6053" /> 117.55 + </linearGradient> 117.56 + <marker 117.57 + inkscape:stockid="Arrow1Mend" 117.58 + orient="auto" 117.59 + refY="0.0" 117.60 + refX="0.0" 117.61 + id="Arrow1Mend" 117.62 + style="overflow:visible;"> 117.63 + <path 117.64 + id="path4852" 117.65 + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " 117.66 + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;" 117.67 + transform="scale(0.4) rotate(180) translate(10,0)" /> 117.68 + </marker> 117.69 + <linearGradient 117.70 + inkscape:collect="always" 117.71 + xlink:href="#linearGradient6049" 117.72 + id="linearGradient6083" 117.73 + gradientUnits="userSpaceOnUse" 117.74 + gradientTransform="translate(-240.0462,-8.633237e-6)" 117.75 + x1="333.91171" 117.76 + y1="488.79077" 117.77 + x2="508.94543" 117.78 + y2="263.79077" /> 117.79 + <linearGradient 117.80 + inkscape:collect="always" 117.81 + xlink:href="#linearGradient6049" 117.82 + id="linearGradient6142" 117.83 + gradientUnits="userSpaceOnUse" 117.84 + gradientTransform="translate(-42.00893,-30.49544)" 117.85 + x1="333.91171" 117.86 + y1="488.79077" 117.87 + x2="508.94543" 117.88 + y2="263.79077" /> 117.89 + <linearGradient 117.90 + inkscape:collect="always" 117.91 + xlink:href="#linearGradient6049" 117.92 + id="linearGradient6193" 117.93 + gradientUnits="userSpaceOnUse" 117.94 + gradientTransform="translate(-240.0462,-8.633237e-6)" 117.95 + x1="333.91171" 117.96 + y1="488.79077" 117.97 + x2="508.94543" 117.98 + y2="263.79077" /> 117.99 + <linearGradient 117.100 + inkscape:collect="always" 117.101 + xlink:href="#linearGradient6049" 117.102 + id="linearGradient6216" 117.103 + gradientUnits="userSpaceOnUse" 117.104 + gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)" 117.105 + x1="333.91171" 117.106 + y1="488.79077" 117.107 + x2="508.94543" 117.108 + y2="263.79077" /> 117.109 + <linearGradient 117.110 + inkscape:collect="always" 117.111 + xlink:href="#linearGradient6049" 117.112 + id="linearGradient6232" 117.113 + gradientUnits="userSpaceOnUse" 117.114 + gradientTransform="matrix(1.000473,0,0,0.790947,-11.16012,50.85693)" 117.115 + x1="333.91171" 117.116 + y1="488.79077" 117.117 + x2="508.94543" 117.118 + y2="263.79077" /> 117.119 + <linearGradient 117.120 + inkscape:collect="always" 117.121 + xlink:href="#linearGradient6049" 117.122 + id="linearGradient6445" 117.123 + gradientUnits="userSpaceOnUse" 117.124 + gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)" 117.125 + x1="333.91171" 117.126 + y1="488.79077" 117.127 + x2="508.94543" 117.128 + y2="263.79077" /> 117.129 + <linearGradient 117.130 + inkscape:collect="always" 117.131 + xlink:href="#linearGradient6049" 117.132 + id="linearGradient6974" 117.133 + gradientUnits="userSpaceOnUse" 117.134 + gradientTransform="matrix(1.000474,0,0,0.790947,-314.246,50.85694)" 117.135 + x1="333.91171" 117.136 + y1="488.79077" 117.137 + x2="508.94543" 117.138 + y2="263.79077" /> 117.139 + <linearGradient 117.140 + inkscape:collect="always" 117.141 + xlink:href="#linearGradient6049" 117.142 + id="linearGradient6996" 117.143 + gradientUnits="userSpaceOnUse" 117.144 + gradientTransform="matrix(1.000473,0,0,0.790947,-85.16012,50.85693)" 117.145 + x1="333.91171" 117.146 + y1="488.79077" 117.147 + x2="508.94543" 117.148 + y2="263.79077" /> 117.149 + </defs> 117.150 + <sodipodi:namedview 117.151 + id="base" 117.152 + pagecolor="#ffffff" 117.153 + bordercolor="#666666" 117.154 + borderopacity="1.0" 117.155 + gridtolerance="10000" 117.156 + guidetolerance="10" 117.157 + objecttolerance="10" 117.158 + inkscape:pageopacity="0.0" 117.159 + inkscape:pageshadow="2" 117.160 + inkscape:zoom="0.64" 117.161 + inkscape:cx="235.37429" 117.162 + inkscape:cy="726.21069" 117.163 + inkscape:document-units="px" 117.164 + inkscape:current-layer="layer1" 117.165 + showguides="true" 117.166 + inkscape:guide-bbox="true" 117.167 + inkscape:window-width="906" 117.168 + inkscape:window-height="659" 117.169 + inkscape:window-x="2" 117.170 + inkscape:window-y="43" 117.171 + showgrid="false"> 117.172 + <sodipodi:guide 117.173 + orientation="vertical" 117.174 + position="-1.4285714" 117.175 + id="guide6022" /> 117.176 + </sodipodi:namedview> 117.177 + <metadata 117.178 + id="metadata5976"> 117.179 + <rdf:RDF> 117.180 + <cc:Work 117.181 + rdf:about=""> 117.182 + <dc:format>image/svg+xml</dc:format> 117.183 + <dc:type 117.184 + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> 117.185 + </cc:Work> 117.186 + </rdf:RDF> 117.187 + </metadata> 117.188 + <g 117.189 + inkscape:label="Layer 1" 117.190 + inkscape:groupmode="layer" 117.191 + id="layer1"> 117.192 + <rect 117.193 + y="245.94225" 117.194 + x="20.198257" 117.195 + height="204.51619" 117.196 + width="174.36833" 117.197 + id="rect6047" 117.198 + style="fill:url(#linearGradient6974);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> 117.199 + <rect 117.200 + style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" 117.201 + id="rect5996" 117.202 + width="134.53746" 117.203 + height="44.537449" 117.204 + x="40.113693" 117.205 + y="266.24374" /> 117.206 + <text 117.207 + xml:space="preserve" 117.208 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 117.209 + x="64.796204" 117.210 + y="292.00446" 117.211 + id="text5998"><tspan 117.212 + sodipodi:role="line" 117.213 + id="tspan6000" 117.214 + x="64.796204" 117.215 + y="292.00446" 117.216 + style="font-family:Courier">e7639888bb2f</tspan></text> 117.217 + <g 117.218 + id="g6976"> 117.219 + <rect 117.220 + y="327.9104" 117.221 + x="40.113693" 117.222 + height="44.537449" 117.223 + width="134.53746" 117.224 + id="rect6004" 117.225 + style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" /> 117.226 + <text 117.227 + id="text6006" 117.228 + y="353.67111" 117.229 + x="62.654205" 117.230 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 117.231 + xml:space="preserve"><tspan 117.232 + style="font-family:Courier" 117.233 + y="353.67111" 117.234 + x="62.654205" 117.235 + id="tspan6008" 117.236 + sodipodi:role="line">7b064d8bac5e</tspan></text> 117.237 + </g> 117.238 + <path 117.239 + inkscape:connection-end="#rect6004" 117.240 + inkscape:connector-type="polyline" 117.241 + id="path6020" 117.242 + d="M 107.38242,311.15529 L 107.38242,327.53626" 117.243 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" /> 117.244 + <rect 117.245 + style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 117.246 + id="rect6039" 117.247 + width="134.53746" 117.248 + height="44.537449" 117.249 + x="40.113571" 117.250 + y="389.57703" /> 117.251 + <text 117.252 + xml:space="preserve" 117.253 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 117.254 + x="64.797073" 117.255 + y="415.33771" 117.256 + id="text6041"><tspan 117.257 + sodipodi:role="line" 117.258 + id="tspan6043" 117.259 + x="64.797073" 117.260 + y="415.33771" 117.261 + style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text> 117.262 + <path 117.263 + inkscape:connection-end="#rect6039" 117.264 + inkscape:connector-type="polyline" 117.265 + id="path6045" 117.266 + d="M 107.38238,372.82195 L 107.38235,389.20301" 117.267 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#686868;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" /> 117.268 + <text 117.269 + xml:space="preserve" 117.270 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 117.271 + x="19.660461" 117.272 + y="231.36218" 117.273 + id="text6102"><tspan 117.274 + sodipodi:role="line" 117.275 + id="tspan6104" 117.276 + x="19.660461" 117.277 + y="231.36218">Historia en el repositorio</tspan></text> 117.278 + <rect 117.279 + y="245.94225" 117.280 + x="249.28412" 117.281 + height="204.51619" 117.282 + width="174.36833" 117.283 + id="rect6140" 117.284 + style="fill:url(#linearGradient6996);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> 117.285 + <g 117.286 + id="g6130" 117.287 + transform="translate(-45.67459,24.38544)"> 117.288 + <rect 117.289 + style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" 117.290 + id="rect6106" 117.291 + width="134.53746" 117.292 + height="44.537449" 117.293 + x="314.87415" 117.294 + y="257.95059" /> 117.295 + <text 117.296 + xml:space="preserve" 117.297 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 117.298 + x="339.55664" 117.299 + y="283.7113" 117.300 + id="text6108"><tspan 117.301 + sodipodi:role="line" 117.302 + id="tspan6110" 117.303 + x="339.55664" 117.304 + y="283.7113" 117.305 + style="font-family:Courier">7b064d8bac5e</tspan></text> 117.306 + </g> 117.307 + <g 117.308 + id="g6135" 117.309 + transform="translate(-44.96042,49.83106)"> 117.310 + <rect 117.311 + inkscape:transform-center-y="102.85714" 117.312 + inkscape:transform-center-x="129.28571" 117.313 + style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 117.314 + id="rect6112" 117.315 + width="134.53746" 117.316 + height="44.537449" 117.317 + x="314.15985" 117.318 + y="326.52203" /> 117.319 + <text 117.320 + inkscape:transform-center-y="102.7311" 117.321 + inkscape:transform-center-x="128.69672" 117.322 + xml:space="preserve" 117.323 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 117.324 + x="338.84335" 117.325 + y="352.28271" 117.326 + id="text6114"><tspan 117.327 + sodipodi:role="line" 117.328 + id="tspan6116" 117.329 + x="338.84335" 117.330 + y="352.28271" 117.331 + style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text> 117.332 + </g> 117.333 + <text 117.334 + xml:space="preserve" 117.335 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 117.336 + x="268.63208" 117.337 + y="270.479" 117.338 + id="text6118"><tspan 117.339 + sodipodi:role="line" 117.340 + id="tspan6120" 117.341 + x="268.63208" 117.342 + y="270.479">Primer padre</tspan></text> 117.343 + <text 117.344 + xml:space="preserve" 117.345 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 117.346 + x="268.07544" 117.347 + y="364.49615" 117.348 + id="text6122"><tspan 117.349 + sodipodi:role="line" 117.350 + id="tspan6124" 117.351 + x="268.07544" 117.352 + y="364.49615">Segundo padre</tspan></text> 117.353 + <text 117.354 + xml:space="preserve" 117.355 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 117.356 + x="248.61746" 117.357 + y="231.36218" 117.358 + id="text6195"><tspan 117.359 + sodipodi:role="line" 117.360 + id="tspan6197" 117.361 + x="248.61746" 117.362 + y="231.36218">Padres del directorio de trabajo</tspan></text> 117.363 + <path 117.364 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline" 117.365 + d="M 268.82543,318.06163 L 175.02528,336.72225" 117.366 + id="path6266" 117.367 + inkscape:connector-type="polyline" 117.368 + inkscape:connection-end="#g6976" 117.369 + inkscape:connection-start="#g6130" /> 117.370 + <path 117.371 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" 117.372 + d="M 665.12232,418.17579 L 665.12232,418.17579" 117.373 + id="path6270" 117.374 + inkscape:connector-type="polyline" /> 117.375 + </g> 117.376 +</svg>
118.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 118.2 +++ b/es/wdir.svg Thu Jan 29 22:00:07 2009 -0800 118.3 @@ -0,0 +1,357 @@ 118.4 +<?xml version="1.0" encoding="UTF-8" standalone="no"?> 118.5 +<!-- Created with Inkscape (http://www.inkscape.org/) --> 118.6 +<svg 118.7 + xmlns:dc="http://purl.org/dc/elements/1.1/" 118.8 + xmlns:cc="http://creativecommons.org/ns#" 118.9 + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 118.10 + xmlns:svg="http://www.w3.org/2000/svg" 118.11 + xmlns="http://www.w3.org/2000/svg" 118.12 + xmlns:xlink="http://www.w3.org/1999/xlink" 118.13 + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" 118.14 + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" 118.15 + width="744.09448819" 118.16 + height="1052.3622047" 118.17 + id="svg5971" 118.18 + sodipodi:version="0.32" 118.19 + inkscape:version="0.46" 118.20 + sodipodi:docbase="/home/bos/hg/hgbook/en" 118.21 + sodipodi:docname="wdir.svg" 118.22 + inkscape:output_extension="org.inkscape.output.svg.inkscape"> 118.23 + <defs 118.24 + id="defs5973"> 118.25 + <inkscape:perspective 118.26 + sodipodi:type="inkscape:persp3d" 118.27 + inkscape:vp_x="0 : 526.18109 : 1" 118.28 + inkscape:vp_y="0 : 1000 : 0" 118.29 + inkscape:vp_z="744.09448 : 526.18109 : 1" 118.30 + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" 118.31 + id="perspective3368" /> 118.32 + <marker 118.33 + inkscape:stockid="Arrow1Mstart" 118.34 + orient="auto" 118.35 + refY="0.0" 118.36 + refX="0.0" 118.37 + id="Arrow1Mstart" 118.38 + style="overflow:visible"> 118.39 + <path 118.40 + id="path4855" 118.41 + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " 118.42 + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none" 118.43 + transform="scale(0.4) translate(10,0)" /> 118.44 + </marker> 118.45 + <linearGradient 118.46 + id="linearGradient6049"> 118.47 + <stop 118.48 + style="stop-color:#686868;stop-opacity:1;" 118.49 + offset="0" 118.50 + id="stop6051" /> 118.51 + <stop 118.52 + style="stop-color:#f0f0f0;stop-opacity:1;" 118.53 + offset="1" 118.54 + id="stop6053" /> 118.55 + </linearGradient> 118.56 + <marker 118.57 + inkscape:stockid="Arrow1Mend" 118.58 + orient="auto" 118.59 + refY="0.0" 118.60 + refX="0.0" 118.61 + id="Arrow1Mend" 118.62 + style="overflow:visible;"> 118.63 + <path 118.64 + id="path4852" 118.65 + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " 118.66 + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;" 118.67 + transform="scale(0.4) rotate(180) translate(10,0)" /> 118.68 + </marker> 118.69 + <linearGradient 118.70 + inkscape:collect="always" 118.71 + xlink:href="#linearGradient6049" 118.72 + id="linearGradient6083" 118.73 + gradientUnits="userSpaceOnUse" 118.74 + gradientTransform="translate(-240.0462,-8.633237e-6)" 118.75 + x1="333.91171" 118.76 + y1="488.79077" 118.77 + x2="508.94543" 118.78 + y2="263.79077" /> 118.79 + <linearGradient 118.80 + inkscape:collect="always" 118.81 + xlink:href="#linearGradient6049" 118.82 + id="linearGradient6142" 118.83 + gradientUnits="userSpaceOnUse" 118.84 + gradientTransform="translate(-42.00893,-30.49544)" 118.85 + x1="333.91171" 118.86 + y1="488.79077" 118.87 + x2="508.94543" 118.88 + y2="263.79077" /> 118.89 + <linearGradient 118.90 + inkscape:collect="always" 118.91 + xlink:href="#linearGradient6049" 118.92 + id="linearGradient6193" 118.93 + gradientUnits="userSpaceOnUse" 118.94 + gradientTransform="translate(-240.0462,-8.633237e-6)" 118.95 + x1="333.91171" 118.96 + y1="488.79077" 118.97 + x2="508.94543" 118.98 + y2="263.79077" /> 118.99 + <linearGradient 118.100 + inkscape:collect="always" 118.101 + xlink:href="#linearGradient6049" 118.102 + id="linearGradient6216" 118.103 + gradientUnits="userSpaceOnUse" 118.104 + gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)" 118.105 + x1="333.91171" 118.106 + y1="488.79077" 118.107 + x2="508.94543" 118.108 + y2="263.79077" /> 118.109 + <linearGradient 118.110 + inkscape:collect="always" 118.111 + xlink:href="#linearGradient6049" 118.112 + id="linearGradient6232" 118.113 + gradientUnits="userSpaceOnUse" 118.114 + gradientTransform="matrix(1.000473,0,0,0.790947,-11.16012,50.85693)" 118.115 + x1="333.91171" 118.116 + y1="488.79077" 118.117 + x2="508.94543" 118.118 + y2="263.79077" /> 118.119 + <linearGradient 118.120 + inkscape:collect="always" 118.121 + xlink:href="#linearGradient6049" 118.122 + id="linearGradient6445" 118.123 + gradientUnits="userSpaceOnUse" 118.124 + gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)" 118.125 + x1="333.91171" 118.126 + y1="488.79077" 118.127 + x2="508.94543" 118.128 + y2="263.79077" /> 118.129 + </defs> 118.130 + <sodipodi:namedview 118.131 + id="base" 118.132 + pagecolor="#ffffff" 118.133 + bordercolor="#666666" 118.134 + borderopacity="1.0" 118.135 + gridtolerance="10000" 118.136 + guidetolerance="10" 118.137 + objecttolerance="10" 118.138 + inkscape:pageopacity="0.0" 118.139 + inkscape:pageshadow="2" 118.140 + inkscape:zoom="1.8101934" 118.141 + inkscape:cx="301.66555" 118.142 + inkscape:cy="721.33993" 118.143 + inkscape:document-units="px" 118.144 + inkscape:current-layer="layer1" 118.145 + showguides="true" 118.146 + inkscape:guide-bbox="true" 118.147 + inkscape:window-width="906" 118.148 + inkscape:window-height="659" 118.149 + inkscape:window-x="355" 118.150 + inkscape:window-y="55" 118.151 + showgrid="false"> 118.152 + <sodipodi:guide 118.153 + orientation="vertical" 118.154 + position="-1.4285714" 118.155 + id="guide6022" /> 118.156 + </sodipodi:namedview> 118.157 + <metadata 118.158 + id="metadata5976"> 118.159 + <rdf:RDF> 118.160 + <cc:Work 118.161 + rdf:about=""> 118.162 + <dc:format>image/svg+xml</dc:format> 118.163 + <dc:type 118.164 + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> 118.165 + </cc:Work> 118.166 + </rdf:RDF> 118.167 + </metadata> 118.168 + <g 118.169 + inkscape:label="Layer 1" 118.170 + inkscape:groupmode="layer" 118.171 + id="layer1"> 118.172 + <g 118.173 + id="g6431" 118.174 + transform="translate(0,-0.137863)"> 118.175 + <rect 118.176 + style="fill:url(#linearGradient6445);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 118.177 + id="rect6047" 118.178 + width="174.36833" 118.179 + height="204.51619" 118.180 + x="94.198257" 118.181 + y="246.08011" /> 118.182 + <rect 118.183 + y="266.38159" 118.184 + x="114.11369" 118.185 + height="44.537449" 118.186 + width="134.53746" 118.187 + id="rect5996" 118.188 + style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" /> 118.189 + <text 118.190 + id="text5998" 118.191 + y="292.1423" 118.192 + x="138.7962" 118.193 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 118.194 + xml:space="preserve"><tspan 118.195 + style="font-family:Courier" 118.196 + y="292.1423" 118.197 + x="138.7962" 118.198 + id="tspan6000" 118.199 + sodipodi:role="line">e7639888bb2f</tspan></text> 118.200 + <rect 118.201 + y="328.04825" 118.202 + x="114.11369" 118.203 + height="44.537449" 118.204 + width="134.53746" 118.205 + id="rect6004" 118.206 + style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" /> 118.207 + <text 118.208 + id="text6006" 118.209 + y="353.80896" 118.210 + x="136.65421" 118.211 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 118.212 + xml:space="preserve"><tspan 118.213 + style="font-family:Courier" 118.214 + y="353.80896" 118.215 + x="136.65421" 118.216 + id="tspan6008" 118.217 + sodipodi:role="line">7b064d8bac5e</tspan></text> 118.218 + <path 118.219 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" 118.220 + d="M 181.38242,311.29315 L 181.38242,327.67412" 118.221 + id="path6020" 118.222 + inkscape:connector-type="polyline" 118.223 + inkscape:connection-end="#rect6004" /> 118.224 + <rect 118.225 + y="389.71487" 118.226 + x="114.11357" 118.227 + height="44.537449" 118.228 + width="134.53746" 118.229 + id="rect6039" 118.230 + style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> 118.231 + <text 118.232 + id="text6041" 118.233 + y="415.47556" 118.234 + x="138.79707" 118.235 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 118.236 + xml:space="preserve"><tspan 118.237 + style="fill:#979797;fill-opacity:1;font-family:Courier" 118.238 + y="415.47556" 118.239 + x="138.79707" 118.240 + id="tspan6043" 118.241 + sodipodi:role="line">000000000000</tspan></text> 118.242 + <path 118.243 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#686868;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" 118.244 + d="M 181.38238,372.95981 L 181.38235,389.34087" 118.245 + id="path6045" 118.246 + inkscape:connector-type="polyline" 118.247 + inkscape:connection-end="#rect6039" /> 118.248 + </g> 118.249 + <text 118.250 + xml:space="preserve" 118.251 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 118.252 + x="93.660484" 118.253 + y="231.36218" 118.254 + id="text6102"><tspan 118.255 + sodipodi:role="line" 118.256 + id="tspan6104" 118.257 + x="93.660484" 118.258 + y="231.36218">Historia en el repositorio</tspan></text> 118.259 + <g 118.260 + id="g6416"> 118.261 + <rect 118.262 + style="fill:url(#linearGradient6232);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 118.263 + id="rect6140" 118.264 + width="174.36833" 118.265 + height="204.51619" 118.266 + x="323.28412" 118.267 + y="245.94225" /> 118.268 + <g 118.269 + transform="translate(28.32541,24.38544)" 118.270 + id="g6130"> 118.271 + <rect 118.272 + y="257.95059" 118.273 + x="314.87415" 118.274 + height="44.537449" 118.275 + width="134.53746" 118.276 + id="rect6106" 118.277 + style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" /> 118.278 + <text 118.279 + id="text6108" 118.280 + y="283.7113" 118.281 + x="339.55664" 118.282 + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 118.283 + xml:space="preserve"><tspan 118.284 + style="font-family:Courier" 118.285 + y="283.7113" 118.286 + x="339.55664" 118.287 + id="tspan6110" 118.288 + sodipodi:role="line">e7639888bb2f</tspan></text> 118.289 + </g> 118.290 + <g 118.291 + transform="translate(29.03958,49.83106)" 118.292 + id="g6135"> 118.293 + <rect 118.294 + y="326.52203" 118.295 + x="314.15985" 118.296 + height="44.537449" 118.297 + width="134.53746" 118.298 + id="rect6112" 118.299 + style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" 118.300 + inkscape:transform-center-x="129.28571" 118.301 + inkscape:transform-center-y="102.85714" /> 118.302 + <text 118.303 + id="text6114" 118.304 + y="352.28271" 118.305 + x="338.84335" 118.306 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 118.307 + xml:space="preserve" 118.308 + inkscape:transform-center-x="128.69672" 118.309 + inkscape:transform-center-y="102.7311"><tspan 118.310 + style="fill:#979797;fill-opacity:1;font-family:Courier" 118.311 + y="352.28271" 118.312 + x="338.84335" 118.313 + id="tspan6116" 118.314 + sodipodi:role="line">000000000000</tspan></text> 118.315 + </g> 118.316 + <text 118.317 + id="text6118" 118.318 + y="270.479" 118.319 + x="342.63208" 118.320 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 118.321 + xml:space="preserve"><tspan 118.322 + y="270.479" 118.323 + x="342.63208" 118.324 + id="tspan6120" 118.325 + sodipodi:role="line">Primer padre</tspan></text> 118.326 + <text 118.327 + id="text6122" 118.328 + y="364.49615" 118.329 + x="342.07544" 118.330 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 118.331 + xml:space="preserve"><tspan 118.332 + y="364.49615" 118.333 + x="342.07544" 118.334 + id="tspan6124" 118.335 + sodipodi:role="line">Segundo padre</tspan></text> 118.336 + </g> 118.337 + <text 118.338 + xml:space="preserve" 118.339 + style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman" 118.340 + x="322.61746" 118.341 + y="231.36218" 118.342 + id="text6195"><tspan 118.343 + sodipodi:role="line" 118.344 + id="tspan6197" 118.345 + x="322.61746" 118.346 + y="231.36218">Padres del directorio de trabajo</tspan></text> 118.347 + <path 118.348 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline" 118.349 + d="M 342.82543,299.89384 L 249.02528,293.36123" 118.350 + id="path6266" 118.351 + inkscape:connector-type="polyline" 118.352 + inkscape:connection-start="#g6130" 118.353 + inkscape:connection-end="#rect5996" /> 118.354 + <path 118.355 + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" 118.356 + d="M 665.12232,418.17579 L 665.12232,418.17579" 118.357 + id="path6270" 118.358 + inkscape:connector-type="polyline" /> 118.359 + </g> 118.360 +</svg>
119.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 119.2 +++ b/html/index.es.html Thu Jan 29 22:00:07 2009 -0800 119.3 @@ -0,0 +1,53 @@ 119.4 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 119.5 +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 119.6 +<html lang="es"> 119.7 + <head> 119.8 + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 119.9 + <link rel="icon" href="/hgicon.png" type="image/png"> 119.10 + <meta name="robots" content="index,follow"> 119.11 + <title>Control Distribuido de Revisiones con Mercurial</title> 119.12 + </head> 119.13 + 119.14 + <body> 119.15 + <h1>Control Distribuido de Revisiones con Mercurial</h1> 119.16 + 119.17 + <p>Bienvenido al sito del libro “Control Distribuido de Revisiones con Mercurial”, en español, 119.18 + por <a href="http://www.serpentine.com/blog/">Bryan O'Sullivan</a>. 119.19 + Este libro está cobijado por una <a href="hgbookap4.html">licencia abierta</a> 119.20 + y trata del sistema de control de revisiones 119.21 + <a href="http://www.selenic.com/mercurial">Mercurial</a>. 119.22 + 119.23 + <p>Los traductores son <a href="http://devnull.li/~jerojasro/blog/">Javier Rojas</a> e 119.24 + <a href="http://igor.tamarapatino.org/">Igor Támara</a>. En este sitio usted puede encontrar: 119.25 + <ul> 119.26 + <li>La <a href="onepage.html">versión HTML</a> una sola página.</li> 119.27 + <li>La <a href="hgbook.pdf">versión PDF</a> (1.9 megabytes.)</li> 119.28 + <li>El <a href="http://mercurial.intuxication.org/hg/mercurial_book_es/">código 119.29 + fuente</a> de la traducción, si desea revisarla o colaborar con el proyecto. En 119.30 + <a href="http://hg.serpentine.com/mercurial/book">este sitio</a> puede 119.31 + encontrar la versión original en inglés.</li> 119.32 + </ul> 119.33 + Para más detalles acerca del proceso de traducción, por favor vea <a 119.34 + href="http://mercurial.intuxication.org/hg/mercurial_book_es/file/tip/es/Leame.1st">este 119.35 + fichero</a>. 119.36 + 119.37 + <h2>¿Cómo puede usted ayudar a Mercurial, y el software libre?</h2> 119.38 + 119.39 + <p>Mercurial es miembro del <a 119.40 + href="http://conservancy.softwarefreedom.org/">Conservatorio 119.41 + de Software Libre</a>, una maravillosa organización sin ánimo 119.42 + de lucro que ofrece a sus proyectos miembros consejo legal y 119.43 + administrativo. La SFC acepta <a href="http://conservancy.softwarefreedom.org/?donate">donaciones</a> 119.44 + (deducibles de impuestos bajo IRS 501(c)(3), dentro de los Estados Unidos) 119.45 + en representación de sus proyectos miembros. Si desea dar un apoyo 119.46 + directo a Mercurial, por favor considere hacer una donación a SFC 119.47 + en su representación.</p> 119.48 + 119.49 + <p>Si desea apoyar a los desarrolladores de software libre en su 119.50 + importante servicio público sin estar impedido por cuestiones 119.51 + legales, por favor considere donar a la organización hermana de 119.52 + SFC, el <a 119.53 + href="http://www.softwarefreedom.org/">Centro de Leyes de Software 119.54 + Libre</a>.</p> 119.55 + </body> 119.56 +</html>
120.1 --- a/html/index.html.var Thu Jan 15 10:13:51 2009 +0100 120.2 +++ b/html/index.html.var Thu Jan 29 22:00:07 2009 -0800 120.3 @@ -1,3 +1,7 @@ 120.4 URI: index.en.html 120.5 Content-Language: en 120.6 Content-Type: text/html; charset=UTF-8 120.7 + 120.8 +URI: index.es.html 120.9 +Content-Language: es 120.10 +Content-Type: text/html; charset=UTF-8