��c
@s
dZyddlZWnek
r5ddlZnXddlZddlZddlmZddlmZddlm Z ddlm
Z
ddlmZddlmZdd lm
Zdd
lmZddlmZddlmZdd
lmZddlmZddlmZddlmZiZeje�ZdZed�Zd�Zd�Zd�Zd�Zd�Z d�Z!d�Z"d�Z#d�Z$de&id�Z'i
ed6ed6e d6e d 6e!d!6e!d"6e#d#6e#d$6e$d%6e$d&6Z(ed'd(d)d(ed*�fd+d,e&ed-�fd.d/e&ed0�fd(d1e&ed2�fd3d4e&ed5�fd!d6e&ed7�fd8d9ged:�fged;��d<��Z)d=�Z*d>�Z+d?�Z,d@�Z-dA�Z.dB�Z/dC�Z0dD�Z1dE�Z2dS(Fs`interactive history editing
With this extension installed, Mercurial gains one new command: histedit. Usage
is as follows, assuming the following history::
@ 3[tip] 7c2fd3b9020c 2009-04-27 18:04 -0500 durin42
| Add delta
|
o 2 030b686bedc4 2009-04-27 18:04 -0500 durin42
| Add gamma
|
o 1 c561b4e977df 2009-04-27 18:04 -0500 durin42
| Add beta
|
o 0 d8d2fcd0e319 2009-04-27 18:04 -0500 durin42
Add alpha
If you were to run ``hg histedit c561b4e977df``, you would see the following
file open in your editor::
pick c561b4e977df Add beta
pick 030b686bedc4 Add gamma
pick 7c2fd3b9020c Add delta
# Edit history between c561b4e977df and 7c2fd3b9020c
#
# Commands:
# p, pick = use commit
# e, edit = use commit, but stop for amending
# f, fold = use commit, but fold into previous commit (combines N and N-1)
# d, drop = remove commit from history
# m, mess = edit message without changing commit content
#
In this file, lines beginning with ``#`` are ignored. You must specify a rule
for each revision in your history. For example, if you had meant to add gamma
before beta, and then wanted to add delta in the same revision as beta, you
would reorganize the file to look like this::
pick 030b686bedc4 Add gamma
pick c561b4e977df Add beta
fold 7c2fd3b9020c Add delta
# Edit history between c561b4e977df and 7c2fd3b9020c
#
# Commands:
# p, pick = use commit
# e, edit = use commit, but stop for amending
# f, fold = use commit, but fold into previous commit (combines N and N-1)
# d, drop = remove commit from history
# m, mess = edit message without changing commit content
#
At which point you close the editor and ``histedit`` starts working. When you
specify a ``fold`` operation, ``histedit`` will open an editor when it folds
those revisions together, offering you a chance to clean up the commit message::
Add beta
***
Add delta
Edit the commit message to your liking, then close the editor. For
this example, let's assume that the commit message was changed to
``Add beta and delta.`` After histedit has run and had a chance to
remove any old or temporary revisions it needed, the history looks
like this::
@ 2[tip] 989b4d060121 2009-04-27 18:04 -0500 durin42
| Add beta and delta.
|
o 1 081603921c3f 2009-04-27 18:04 -0500 durin42
| Add gamma
|
o 0 d8d2fcd0e319 2009-04-27 18:04 -0500 durin42
Add alpha
Note that ``histedit`` does *not* remove any revisions (even its own temporary
ones) until after it has completed all the editing operations, so it will
probably perform several strip operations when it's done. For the above example,
it had to run strip twice. Strip can be slow depending on a variety of factors,
so you might need to be a little patient. You can choose to keep the original
revisions by passing the ``--keep`` flag.
The ``edit`` operation will drop you back to a command prompt,
allowing you to edit files freely, or even use ``hg record`` to commit
some changes as a separate commit. When you're done, any remaining
uncommitted changes will be committed as well. When done, run ``hg
histedit --continue`` to finish this step. You'll be prompted for a
new commit message, but the default commit message will be the
original message for the ``edit`` ed revision.
The ``message`` operation will give you a chance to revise a commit
message without changing the contents. It's a shortcut for doing
``edit`` immediately followed by `hg histedit --continue``.
If ``histedit`` encounters a conflict when moving a revision (while
handling ``pick`` or ``fold``), it'll stop in a similar manner to
``edit`` with the difference that it won't prompt you for a commit
message when done. If you decide at this point that you don't like how
much work it will be to rearrange history, or that you made a mistake,
you can use ``hg histedit --abort`` to abandon the new changes you
have made and return to the state before you attempted to edit your
history.
If we clone the histedit-ed example repository above and add four more
changes, such that we have the following history::
@ 6[tip] 038383181893 2009-04-27 18:04 -0500 stefan
| Add theta
|
o 5 140988835471 2009-04-27 18:04 -0500 stefan
| Add eta
|
o 4 122930637314 2009-04-27 18:04 -0500 stefan
| Add zeta
|
o 3 836302820282 2009-04-27 18:04 -0500 stefan
| Add epsilon
|
o 2 989b4d060121 2009-04-27 18:04 -0500 durin42
| Add beta and delta.
|
o 1 081603921c3f 2009-04-27 18:04 -0500 durin42
| Add gamma
|
o 0 d8d2fcd0e319 2009-04-27 18:04 -0500 durin42
Add alpha
If you run ``hg histedit --outgoing`` on the clone then it is the same
as running ``hg histedit 836302820282``. If you need plan to push to a
repository that Mercurial does not detect to be related to the source
repo, you can add a ``--force`` option.
i�N(tcmdutil(t discovery(terror(tcopies(tcontext(thg(tlock(tnode(trepair(tscmutil(tutil(tobsolete(tmerge(t_tinternals&# Edit history between %s and %s
#
# Commands:
# p, pick = use commit
# e, edit = use commit, but stop for amending
# f, fold = use commit, but fold into previous commit (combines N and N-1)
# d, drop = remove commit from history
# m, mess = edit message without changing commit content
#
cs%�j�����fd�}|S(s>Build a commit function for the replacement of <src>
This function ensure we apply the same treatment to all changesets.
- Add a 'histedit_source' entry in extra.
Note that fold have its own separated logic because its handling is a bit
different and not easily factored out of the fold method.
cs��jjdd�}zY�jjdd��|jdi�j�}�j�|d<||d<�j|�SWd�jj|�XdS(Ntphasess
new-committextrathistedit_source(tuitbackupconfigt setconfigtgettcopythextcommitt
restoreconfig(tkwargstphasebackupR(tphasemintrepotsrc(s2/sys/lib/python2.7/site-packages/hgext/histedit.pyt
commitfunc�s
(tphase(RRR((RRRs2/sys/lib/python2.7/site-packages/hgext/histedit.pyt
commitfuncfor�s
cCs|jj�d}|j�j�|krYtj||||tjfdt�d}n�zV|j j
dd|jdd��tj
||j�ttt|j�j��}Wd|j j
ddd�X|j|tj�|jj�tj||j�|j�j��|S(s@Merge changeset from ctx (only) in the current working directoryitallRt
forcemergettooltN(tdirstatetparentstp1RRtreverttnullidtTruetNoneRRRtmergemodtupdatetFalset
setparentstwritetduplicatecopiestrev(RRtctxtoptstwcpartstats((s2/sys/lib/python2.7/site-packages/hgext/histedit.pytapplychanges�s% "
%cs�t|jd|���}|s%d
S|j�d�t�}x!|D]}|j|j��qEWtj|�����fd�}g|D]}||�s�|^q�}�j�����fd�} |j d�r�d}
n|j
�}
|j d�}|j d�}|j d�}
|j�j�|j
�j�f}tj|d |d
|
d|d| d|d|d|
�}tj||g�|_|j|�S(s�collapse the set of revisions from first to last as new one.
Expected commit options are:
- message
- date
- username
Commit message is edited in all cases.
This function works in memory.s%d::%dics�|�j�krw�j|�}|�j�krp�j|�}|j�|j�koo|j�|j�kStSn|�j�kSdS(N(tmanifesttfilectxtdatatflagsR/(tftatb(tbasetlast(s2/sys/lib/python2.7/site-packages/hgext/histedit.pytsamefile�sc
sx|�krk�|}|j�}tj|j�|j�dd|kdd|kd�j|��}|St��dS(Ntislinktltisexectxtcopied(R<Rt
memfilectxtpathR;RtIOError(RR4RItfctxR<tmctx(RGtheadmfRA(s2/sys/lib/python2.7/site-packages/hgext/histedit.pyt filectxfn
s
tmessagetusertdateRR'ttexttfilesRNN(tlisttsetR,R'R.RSRt
pathcopiesR9RtdescriptionR(Rtp2RtmemctxRtcommitforceeditort_textt commitctx(RtfirstRAt
commitoptstctxsRSR4RBR=RNRORPRQRR'tnew((R@RGRMRAs2/sys/lib/python2.7/site-packages/hgext/histedit.pytcollapse�s:
%
$ c
Cs8||}|j�d|kr;|jd|�|gfStj||j��t||||�}|r�|ddkr�tjtd���nt ||�}|d|j
�d|j�d|j�d|j
��}|dkr|jtd �tj|��|gfS||} | |j�|ffgfS(
Nisnode %s unchanged
is0Fix up the change and run hg histedit --continueRRRPRQRs%s: empty changeset
(R'tdebugRR.RR8RtInterventionRequiredR
R!RWRPRQRR,twarnR(
RRR4thaR5toldctxR7RtnR`((s2/sys/lib/python2.7/site-packages/hgext/histedit.pytpick)s"
cCsL||}tj||j��t||||�tjtd���dS(Ns|Make changes as needed, you may commit or record as needed now.
When you are finished, run hg histedit --continue to resume.(RR.RR8RRcR
(RRR4ReR5Rf((s2/sys/lib/python2.7/site-packages/hgext/histedit.pytedit?s
c
Cs�||}tj||j��t||||�}|rc|ddkrctjtd���n|jdd|d|j�d|j �d|j
��}|dkr�|jtd �tj
|��|gfSt||||||g�S(
Niis0Fix up the change and run hg histedit --continueRRsfold-temp-revision %sRPRQRs%s: empty changeset(RR.RR8RRcR
RRPRQRR,RdRt
finishfold(RRR4ReR5RfR7Rg((s2/sys/lib/python2.7/site-packages/hgext/histedit.pytfoldGs
cCs&|j�dj�}tj||�|j�}|j�|j�krY|j�} n|j�} | |d<dj|j�gg|D]}
||
j�^q�|j�g�d}||d<t |j
�|j
��|d<|j�j�}d|j�|j�f|d<||d <|j
jd
d�}
zNt |j�|j��}|j
jd
d|�t|||||�}Wd|j
j|
�X|dkr�|gfStj||�|j�|ff|j�|ff||ffg}x$|D]}|j||ff�q�||fS(NiRPs
***
s
RORQs%s,%sRRRs
new-commit(R'RRR.RRPtusernametjoinRWtmaxRQRRRRR RRaRR,tappend(RRR4RftnewnodeR5tinternalchangestparentR^Rltrt
newmessageRRRRgtreplacementstich((s2/sys/lib/python2.7/site-packages/hgext/histedit.pyRjVs<
-
cCs|||j�dfgfS(N((R(RRR4ReR5((s2/sys/lib/python2.7/site-packages/hgext/histedit.pytdrop�sc
Cs||}tj||j��t||||�}|rc|ddkrctjtd���n|j�d}|j||j ��}t
||�}|d|d|j�d|j�d|j
��} || }
|j�|
j�kr|
|j�| ffgfS|
gfS( Niis0Fix up the change and run hg histedit --continues
RRRPRQR(RR.RR8RRcR
RWRiRlR!RPRQR(RRR4ReR5RfR7RORR`tnewctx((s2/sys/lib/python2.7/site-packages/hgext/histedit.pyRO�s
$
cCs�|j|pd|pd�}tj|d�d \}}|jtd�tj|��tj|||d�\}}tj |||�}|r�g|D]} |j
| �^q�}ntj|||d|�}
|
j
s�jtd���n|
j
dS( sVutility function to find the first outgoing changeset
Used by initialisation codesdefault-pushtdefaultiscomparing with %s
tforcesno outgoing ancestorsiN(t
expandpathRtparseurlR,tstatusR
R
thidepasswordt
addbranchrevstpeertlookupRtfindcommonoutgoingtmissingtAbort(RRtremoteRzR5tdesttrevstcheckouttotherR3toutgoing((s2/sys/lib/python2.7/site-packages/hgext/histedit.pytfindoutgoing�s % tpRhteRiR=RktdRwtmtmessthisteditR%tcommandss+Read history edits from the specified file.tctcontinues$continue an edit already in progresstktkeeps,don't strip old nodes after edit is completetabortsabort an edit in progresstoR�s#changesets not found in destinationRzs.force outgoing even for unrelated repositoriesRsR3sfirst revision to be editeds[PARENT]c+ s-t�dd�}|r9|jr9tjtd���n|jd�}|jd�}|jd�}|jd�}|jdd�} |jd g�}
d
}|r�|r�tjtd���n|r tj|||
|| f�rtjtd���nd}n|rKtj||
|| f�rBtjtd
���nd}n�tj j
tj j�j d��r�tjtd���n|r�|
r�tjtd���nt|�dkrtjtd���qn7|
j
|�t|
�dkrtjtd���n|dkr�t��\}} }
}}�jj�\}}�|}t|�|| |�\}}|j
|�n|dkr8t��\}} }
}}t�|�\}}}}|jdtj|��tj�|�t|�d|�t|�d|�tjtj j�j d��dStj���jj�\}}|r�|rs|d}nd}t|�|||�}n"|
d}tj�|�j�}|jdt�}
t �|||
�}
|
stjtd�tj|���ng|
D]}�|^q}| s�djg|D]}t!|�^q8�} | d7} | t"tj|�tj|�f7} |j#| |j$��} t%�jd�d�}|j&| �|j'�n:| dkr�(j)}nt%| �}|j*�} |j'�gd �| j+�D�D]#}|r|dd!kr|^q} t,| �|�} �|j�d}|jdt�}
g}x�| rt-�|j�| |
||�| j.d�\} }!|jd"| |!f�t/| }"|"|�||!|�\}}#|j
|#�q�Wtj0�|j��t�|�\}}}$}%|rx�|j1�D]�\}&}'|'s�|jd#tj|&��qV|jd$tj|&�tj|'d�f�t|'�dkrVd%}(x/|'dD] })|j|(tj|)��q�WqVqVWn|
s�|r(t2|�|||%�nt3j4r�g}*xWt5|d&�j6j7�D]=}&||&}'|*j8�|&t9�fd'�|'D��f�qPW|*r�t3j:�|*�q�q�t|�d(|�nt|�d|�tjtj j�j d��tj j
�j;d)��r)tj�j;d)��ndS(*s)interactively edit changeset history
tmqssource has mq patches appliedR�R�R�RzR�R%R3R`s$--force only allowed with --outgoings$no arguments allowed with --continues!no arguments allowed with --abortshistedit-states;history edit already in progress, try --continue or --aborts$no revisions allowed with --outgoingis.only one repo argument allowed with --outgoings-histedit requires exactly one parent revisionsrestore wc to old parent %s
tcreatedttempNiR�s*%s is not an ancestor of working directorys
s
shistedit-last-edit.txttwt-css|]}|j�VqdS(N(tstrip(t.0Rs((s2/sys/lib/python2.7/site-packages/hgext/histedit.pys <genexpr>(st#shistedit: processing %s %s
shistedit: %s is dropped
shistedit: %s is replaced by %s
s'histedit: %stkeyc3s|]}�|VqdS(N((R�ts(R(s2/sys/lib/python2.7/site-packages/hgext/histedit.pys <genexpr>Rstreplacedtundo(<tgetattrR,tappliedR
R�R
RtanytosRItexistsRmtlentextendt readstateR&R'tbootstrapcontinuetprocessreplacementRbRtshortRtcleantcleanupnodetunlinkRt
bailifchangedR�R t revsingleR/tbetweentmakedescteditcommentRiRltopenR1tclosetsyststdintreadt
splitlinestverifyrulest
writestatetpoptactiontableR.t iteritemst
movebookmarksRt_enabledtsortedt changelogR3Rottuplet
createmarkerstsjoin(+RRtfreeargsR5R�toutgtcontR�RztrulesR�tgoalt
parentctxnodeR�ttopmostRut
currentparenttwantnullt parentctxtrepltmappingttmpnodestleafst_ntmtemptyR�trootRsR_R�R=RDtactionRetactfunctreplacement_R�tntmtprectsuccsR�Rgtmarkers((Rs2/sys/lib/python2.7/site-packages/hgext/histedit.pyR��s�
$
(
&
#
$(
$cCs~|jd�\}}||}g|jd|�D]}|j�^q2} |j�tjkr�| s�td�}
td�|}tj|
|d|��n| jd�nd}|j�d \}
}}}|
s�s�s�r�|dkrd |}n|j �d
}|dkr(t
j}nt}t
||�}|d|d|j�d|j�d|j�d|�}|dk r�| j|�q�ng}|j�| kr�|j|j�t| �f�n|dkr]| r8|dkr�d}n
| j�t||||||| �\}}|j|�qt|j|j�|j�ff�n| rt|| d}n||fS(Nis(%d::.)s*%s is not an ancestor of working directorysAupdate to %s or descendant and run "hg histedit --continue" againthintiR=Rksfold-temp-revision %ss
R�RiR�R�RRRPRQRteditori�(R=sfold(R�seditR�R�(R=sfold(R�RURR*R
R
R�R,R}RWRRZR/R!RPRQRRoR�RjR�(RRR�R�R5R�tcurrentnodeR4R�tnewchildrentmsgR�R`R�R>RsR�ROR�RRuR�((s2/sys/lib/python2.7/site-packages/hgext/histedit.pyR�^sP
+
"
%cCs�t|jd||��}|r�|r�tjr_|jd||�r_tjtd���n|d}|j�s�tjtd�|��q�ng|D]}|j �^q�S(soselect and validate the set of revision to edit
When keep is false, the specified set can't have children.s%n::%ns(%ld::) - (%ld)s+cannot edit history that would orphan nodesis#cannot edit immutable changeset: %s(
RTRURR�R�R
R�R
R R(RtoldR`R�R_R�R�((s2/sys/lib/python2.7/site-packages/hgext/histedit.pyR��s
cCsNttjj|jd�d�}tj|||||f|�|j�dS(Nshistedit-stateR�(R�R�RIRmtpickletdumpR�(Rt
parentnodeR�R�R�Rutfp((s2/sys/lib/python2.7/site-packages/hgext/histedit.pyR��s!cCs+ttjj|jd��}tj|�S(sIReturns a tuple of (parentnode, rules, keep, topmost, replacements).
shistedit-state(R�R�RIRmR�tload(RR�((s2/sys/lib/python2.7/site-packages/hgext/histedit.pyR��scCsLd}|j�r+|j�j�d}nd||j�|f}|d S(slbuild a initial action line for a ctx `c`
line are in the form:
pick <hash> <rev> <summary>
R%is
pick %s %d %siP(RWR�R3(R�tsummarytline((s2/sys/lib/python2.7/site-packages/hgext/histedit.pyR��s
cCs�g}td�|D��}t�}xB|D]:}d|krZtjtd�|��n|jdd�\}}|j�jdd�d} yt|| �} Wn-tjk
r�tjtd�| ��nX| |kr�jtd���n| |krtjtd�| ��n|j | �|t
krStjtd �|��n|j|| g�q,Wt||�}
|
r�tjtd
�|
ddtd���n|S(
s�Verify that there exists exactly one edit rule per given changeset.
Will abort if there are to many or too few rules, a malformed rule,
or a rule on a changeset outside of the user-given range.
css|]}t|�VqdS(N(tstr(R�R�((s2/sys/lib/python2.7/site-packages/hgext/histedit.pys <genexpr>�st smalformed line "%s"iisunknown changeset %s listeds1may not use changesets other than the ones listeds#duplicated command for changeset %ssunknown action "%s"smissing rules for changeset %sR�s#do you want to use the drop action?(
RUR
R�R
tsplitR�R�Rt RepoErrortaddR�RoR�(R�RR_tparsedtexpectedtseenRsR�trestReR�((s2/sys/lib/python2.7/site-packages/hgext/histedit.pyR��s4
cCs�t�}t�}i}xT|D]L}|j|d�|j|d�|j|dt��j|d�qW||}||@}t|�}i} x�|r-x�t|�D]{}
||
}xht|�D]C}||kr�Pq�|| kr�|j|�|j| |�q�q�W|| |
<|j|
�q�Wq�Wx|D]
}
| |
=q5W|jj}x3| j�D]%\}}t |d|j
�| |<q_W|r�t |d|jj�d}n;| s�d}n,|t | d|jj�dj
�j�}| |||fS(s�process the list of replacements to return
1) the final mapping between original and created nodes
2) the list of temporary node created by histedit
3) the list of new commit created by histeditiiR�i�N(RUR.R�t
setdefaultRTtremoveR�tnodemaptitemsR�RR3R,R(R(RRutallsuccsR�tfullmappingtrepR`R�t toproceedtfinalRFR�R�RgtnmR�t
newtopmost((s2/sys/lib/python2.7/site-packages/hgext/histedit.pyR��sB
(
,cCsQ|s
dSg}x�t|jj��D]�\}}||krW|j||f�q&n|}|j|d�} | dkr�q&nx5| s�||j�j�}|j||f�} q�W|j|| df�q&W|rM|j}
xZ|D]R\}} |
|}|jt d�|tj
|�tj
| �f�| |
|<q�|
j�ndS(s,Move bookmark from old to newly created nodeNi�s,histedit: moving bookmarks %s from %s to %s
(R�t
_bookmarksR�RoRR,R(RtnoteR
R�R1(RRR�t
oldtopmostRtmovestbkR�R@R`tmarkstmark((s2/sys/lib/python2.7/site-packages/hgext/histedit.pyR�$s."
#c Cs�|jd|djg|D]}tj|�^q�f�d}z�|j�}|jj}g|D]}||krd|^qd}g|jd|�D]}|j�^q�}x!|D]}t j
|||�q�WWdtj|�XdS(sdstrip a group of nodes from the repository
The set of node to strip may contains unknown nodes.sshould strip %s nodes %s
s, s
roots(%ln)N(
RbRmRR�R,RR�R�RURR�tlockmodtrelease( RRtnametnodesRgRRR�troots((s2/sys/lib/python2.7/site-packages/hgext/histedit.pyR�Fs 3%+
(3t__doc__tcPickleR�tImportErrorR�R�t mercurialRRRRRRRR
RRR R
RRR-tmercurial.i18nR
tcmdtabletcommandt
testedwithR�R!R8RaRhRiRkRjRwROR,R/R�R�R�R�R�R�R�R�R�R�R�R�(((s2/sys/lib/python2.7/site-packages/hgext/histedit.pyt<module>�s�
F +
�B
! ; "
|