Nathan Durnan avatar Nathan Durnan committed cf8afdc Merge

Merge with Release 0.2.3

Comments (0)

Files changed (4)

 syntax: glob
 *.pyo
+*.pyc
 {
 "Version": "0.2.2",
 "FileData":{
-".hgignore": {"timestamp": 1305849292.78},
+".hgignore": {"timestamp": 1336516662.38},
 ".hgtags": {"timestamp": 1335472415.78},
-"README.md": {"timestamp": 1335570641.45},
+"README.md": {"timestamp": 1337016337.19},
 "TimeStampMod.png": {"timestamp": 1305052883.0},
-"TimestampMod.py": {"timestamp": 1335470448.61},
+"TimestampMod.py": {"timestamp": 1338440223.52},
 "TimeStampMod.xmind": {"timestamp": 1306451621.66},
 "TimestampMod_LastRecord": {"timestamp": 0}
 }
 TimestampMod
 ============
-About (version 0.2.2 beta)
+About (version 0.2.3 beta)
 --------------------------
 TimestampMod is an extension for Mercurial DVCS that incorporates automatic saving and restoring of the modification times of files under version control.  This extension is based on an original timestamp extension by [Friedrich Kastner-Masilko](mailto:face@snoopie.at) hosted at [https://bitbucket.org/face/timestamp][ts].
 
 This extension was developed for use with the following:
 
  - [TortoiseHg][thg] 2.0.4 (or later)
- - [Mercurial][hg] 1.8.3 (or later, included with TortoiseHg)
+    - Required Mercurial and Python libraries  
+      are already included with TortoiseHg.
+ - [Mercurial][hg] 1.8.3 (or later)
+    - [Python][py] 2.6 (or later) must be present when using  
+      a stand-alone (command line) Mercurial installation.
 
 [thg]: http://tortoisehg.bitbucket.org/
 [hg]: http://mercurial.selenic.com/
+[py]: http://python.org/
 
-Note that only Mercurial is required for the use of this extension.  However, there are some peculiarities in the code specific to use with TortoiseHg.  It may also be worth noting that this extension was developed and tested only on Windows XP SP3, so functionality under other operating systems my not be one-hundred-percent reliable.
+Note that only Mercurial is required for the use of this extension.  However, there are some configuration requirements that are specific to either command line Mercurial or TortoiseHg.
+
+It may also be worth noting that this extension was developed and tested only on Windows XP SP3, so functionality under other operating systems my not be one-hundred-percent reliable.
+
 
 - - -
 Installation
 ------------
-Begin by downloading the [TimestampMod.py][dl] file and saving it on your computer.  A typical location for the file would be in an "Extensions" under the TortoiseHg program folder (usually "C:\Program Files\TortoiseHg\").  Note that this is not a default folder in the TortoiseHg installation, and must be added manually.
+#### 1. Download the Extension
+Download the [TimestampMod.py][dl] file and saving it on your computer.  A typical location for the file would be in an "Extensions" under the TortoiseHg program folder (usually "C:\Program Files\TortoiseHg\").  Note that this is not a default folder in the TortoiseHg installation, and must be added manually.
 
 [dl]: https://bitbucket.org/nedmech/timestampmod/downloads/TimestampMod.py
 
-Then edit the appropriate configuration file:
+#### 2. Configure the Extension
+Edit the appropriate configuration file:
 
 - The global configuration file - either:
     1. **mercurial.ini** for TortoiseHg, or 
     2. **hgrc** for a stand-alone Mercurial installation.
 - Each individual repository configuration file (**.hg\\hgrc**) where the extension is to be used.
 
-Add an entry into the extensions section of the configuration file similar to the following::
+Add an entry into the extensions section of the configuration file similar to the following:
     
-    [extensions]
-    TimestampMod = /path/to/TimestampMod.py
+	[extensions]
+	TimestampMod = C:\Program Files\TortoiseHg\Extensions\TimestampMod.py
 
-If using TortoiseHg, some of the hooks will need to be manually configured.  Add entries into the hooks section of the configuration file (**mercurial.ini**) similar to the following::
+Adjust the path as needed to match your installation.
+
+#### 3. Special Configuration for TortoiseHg
+If using TortoiseHg, some of the hooks will need to be manually configured.  Add entries into the hooks section of the configuration file (**mercurial.ini**) similar to the following:
     
-    [hooks]
-    post-merge.TimestampMod = python:/path/to/TimestampMod.py:Hook_Post_Merge
-    post-resolve.TimestampMod = python:/path/to/TimestampMod.py:Hook_Post_Resolve
-    post-revert.TimestampMod = python:/path/to/TimestampMod.py:Hook_Post_Revert
+	[hooks]
+	post-merge.TimestampMod = python:C:\Program Files\TortoiseHg\Extensions\TimestampMod.py:Hook_Post_Merge
+	post-resolve.TimestampMod = python:C:\Program Files\TortoiseHg\Extensions\TimestampMod.py:Hook_Post_Resolve
+	post-revert.TimestampMod = python:C:\Program Files\TortoiseHg\Extensions\TimestampMod.py:Hook_Post_Revert
 
-Nothing further is required to make the extension work.  It will set up it's own hooks that will trigger during committing and updating actions automatically.
+Adjust the paths as needed to match your installation.
+
+#### 4. Additional Steps for Command Line Mercurial
+When this extension is used with the command line Mercurial package (installed separately from TortoiseHg), an additional [Python][py] package must be referenced.  The [Python][py] package that is distributed with the command line Mercurial installation (as of version 2.1.2) is missing some of the library elements needed by this extension.  The package that is distributed with TortoiseHg (version 2.0.5+) is sufficient, or a full [Python][py] package may be installed.  
+
+Download and install at least [Python 2.6.6][pydl] from:  
+
+[http://python.org/download/releases/2.6.6/][pydl]
+  
+[pydl]: http://python.org/download/releases/2.6.6/  
+
+After installing TortoiseHg or Python, the extension must be informed of the Python library path so it can access the required library components.  Add a 'paths' section and entry to the configuration file (**mercurial.ini** or **hgrc**) similar to the following:
+
+	[paths]
+	PythonLibPath = C:\Python26\lib
+
+or  
+
+	[paths]
+	PythonLibPath = C:\Program Files\TortoiseHg\library.zip
+
+Adjust the path as needed to match your installation.
+
+#### 5. Testing the Installation
+
+Open any command prompt and issue the following command to check of the extension is properly installed:
+
+	hg help timestamp_mod
+
+If the installation was installed correctly, the output should be similar to the following:
+
+	C:\>hg help timestamp_mod
+	hg timestamp_mod [-s | -r]
+	
+	C:\Program Files\TortoiseHg\Extensions\TimestampMod.py
+	  (Version 0.2.3)
+	
+	Save or restore file modification times.
+	
+	options:
+	
+	 -s --save    save modification times
+	 -r --restore restore modification times
+	
+	use "hg -v help timestamp_mod" to show more info
+	
+	C:\>
+
+Nothing further is required to make the extension work.  It will automatically save and restore timestamps for all files tracked in the repository during commit and update actions.
 
 - - -
 Release Notes:
 --------------
 These release notes will not cover every version, just tip of the repository and previous major release points.
 
-### __0.2.2 (beta)__ - _April 26, 2012_
-This is a feature change beta release.  The format of the timestamp file (.hgtimestamp) has changed with this release in order to be more forward-compatible.  
+### __0.2.3 (beta)__ - _May 14, 2012_
+This is a bug-fix release.  
 **ALL USERS OF v0.2.x ARE URGED TO UPDATE TO THIS VERSION!**
 
 + __Changed__ - Features or functionality modified with this version:
-    * The timestamp file (.hgtimestamp) format has been modified to allow better forward-compatibility.  This mean that from this version and those following, any additional modifications to the timestamp file should not break compatibility with previous versions (at least back to v0.2.2).
+    * The extension will abort running the Post-Merge and Post-Resolve hooks until there are no unresolved files.  Command line merge tools can leave extra lines in unresolved files to help with manual merging.  This makes it impossible for the extension to read the JSON timestamp file.  Since unresolved files indicate an intermediate merge state, reapplying the timestamps to the unresolved state would likely be incorrect in the first place.
+    _(changed in TimestampMod v0.2.3)_
 
-### __0.2.1 (beta)__ - _April 24, 2012_
-This is a major beta release.  The format of the timestamp file (.hgtimestamp) has changed with this release!
++ __Fixed__ - Issues fixed with this version:
+    * A compatibility issue with the command line Mercurial package was fixed.  The Python library distributed with the command line Mercurial package does not include the JSON module!  A separate Python installation is required for use with the command line Mercurial package.  The extension can now reference an external Python library to pick up the components it needs that may be missing from Mercurial or TortoiseHg native Python libraries.  
+    _(fixed in TimestampMod v0.2.3)_
+
+### __0.2.2 (beta)__ - _April 26, 2012_
+This is a feature change beta release.  The format of the timestamp file (.hgtimestamp) has changed with this release in order to be more forward-compatible.  
 
 + __Changed__ - Features or functionality modified with this version:
-    * The timestamp file (.hgtimestamp) format has changed from a simple CSV file to JSON format in order to accommodate filenames with commas or other non-text characters.
+    * The timestamp file (.hgtimestamp) format has been modified to allow better forward-compatibility.  This mean that from this version and those following, any additional modifications to the timestamp file should not break compatibility with previous versions (at least back to v0.2.2).  
+    _(changed in TimestampMod v0.2.2)_
++ __Changed__ - Features or functionality modified with this version:
+    * The timestamp file (.hgtimestamp) format has changed from a simple CSV file to JSON format in order to accommodate filenames with commas or other non-text characters.  
+    _(changed in TimestampMod v0.2.1)_
 + __Fixed__ - Issues fixed with this version:
     * Timestamps are not restored for files with a comma in the filename.  This is because the timestamp file (.hgtimestamp) was previously a simple CSV file.  Anything after the first comma on a line was treated as the timestamp value.  
     _(fixed in TimestampMod v0.2.1)_
 Every attempt is made to keep this extension up-to-date and in working order,but there are occasional problems that arise in the development process.  These issues will be noted here, and possible work-around recommendations provided if at all possible.
 
 * Support has been added for restoring timestamps of individual files or groups  of files when the "Revert" command is used.  This features works well using Mercurial directly (command-line), but does not work at all for most TortoiseHg menu command and dialogs.  As of TortoiseHg 2.2.2, there is an [outstanding issue][thg1347] with how the "Revert" command has been implemented within TortoiseHg that does not allow it to take advantage of the hooks from extensions like this one.  Currently (TortoiseHg 2.2.2), the only command that seems to work from TortoiseHg is the Windows Explorer context menu "TortiseHg -> Revert Files..." item.
-* Because the timestamp record file is modified on *every* commit, there are nearly always merge conflicts with the timestamp file.  Most of the time, these are trivial and can be resolved with a simple "Tool Resolve" option.  Manually resolving the differences is not too difficult either.  Just keep in mind that a larger timestamp number means a newer timestamp.  This issue can affect any commands that involve merging such as graft or import (when dealing with patches).  No further work will be done on this issue.  After spending much time imagining how this could be automated, it was decided that it is best left to the user to determine the most appropriate timestamps to keep when merging the timestamp file.
+* Because the timestamp record file is modified on *every* commit, there are nearly always merge conflicts with the timestamp file.  Most of the time, these are trivial and can be resolved with a simple "Tool Resolve" option.  Manually resolving the differences is not too difficult either.  Just keep in mind that a larger timestamp number means a newer timestamp.  The timestamps are stored as Unix Epoch values, so they may be manually decoded/encoded if needed as well.  This issue can affect any commands that involve merging such as graft or import (when dealing with patches).  No further work will be done on this issue.  After spending much time imagining how this could be automated, it was decided that it is best left to the user to determine the most appropriate timestamps to keep when merging the timestamp file.
 
 [thg1347]: https://bitbucket.org/tortoisehg/thg/issue/1347/add-support-for-pre-and-post-hooks
 
 # end help text
 #==============================================================================
 # TimestampMod.py - Automatically save and restore the modification times of files
-File_Version = '0.2.2'	# Version number definition
+File_Version = '0.2.3'	# Version number definition
 # --> !!BETA RELEASE!!! <--
 # Copyright 2011-2012 Nathan Durnan <nedmech@gmail.com>
 #
 #	recorded and restored during commit, update, revert, etc. operations.
 #
 # Development information:
-#	Mercurial Version:	1.8.3 - 2.1.1 (from TortoiseHg package)
+#	Mercurial Version:	1.8.3 - 2.2.1 (from TortoiseHg package)
 #	Python Version:		2.6.6 (from TortoiseHg package)
-#	TortoiseHg Version: 2.0.4 - 2.3.1
+#	TortoiseHg Version: 2.0.4 - 2.4.0
 #==============================================================================
 
 #==============================================================================
 import inspect	#required for getting path/name of current code module.
 from mercurial import localrepo	#required for creating a pseudo-pre-commit hook.
 from mercurial import match as matchmod	#required for "match" object in commit wrapper.
+from mercurial import merge as mergemod	#required for merge state (check unresolved)
 from mercurial import cmdutil	#required for working with "Revert" command methods.
 from mercurial import commands	#required for working with "Revert" command methods.
 #_ end of imported modules_____________________________________________________
 def reposetup(ui, repo):
 	'''Initialize Repository-Level Callback'''
 	ui.debug('* Loading TimestampMod reposetup\n')
+	#Check for external Python library path in configuration
+	# NOTE: keep this in reposetup in case user has configured the 
+	#   extension to be used per-repository instead of globally.
+	#   This will ensure the path config can be picked up from
+	#   either the global config or the repository config.
+	sPythonLibPath = str(ui.config('paths', 'PythonLibPath'))
+	if os.path.exists(sPythonLibPath):
+		sys.path.append(sPythonLibPath)
+	#end of check for external Python path
 	ui.setconfig("hooks", "update.TimestampMod", Hook_Update)
 	if not hasattr(localrepo.localrepository, "timestamp_origcommit"):
 		'''This is a "dirty" method of wrapping the commit event so
 def Wrap_Commit(repo, text="", user=None, date=None, match=None, force=False, editor=False, extra={}):
 	repo.ui.note('TimestampMod|Wrap_Commit accessed!\n')
 	#Check for a merge-commit. 
-	#  Don't run timestamp code on merge.
+	#  Don't run timestamp code until merge is complete.
 	if (len(repo.parents()) > 1):
 		repo.ui.status('TimestampMod|Wrap_Commit aborted - Merge in progress\n')
 	else:
 # Hook_Pre_Commit is depreciated in favor of Wrap_Commit method
 #	(Wrap_Commit works with both native Mercurial and TortoiseHg.)
 '''def Hook_Pre_Commit(repo, **kwargs):
-	repo.ui.note("Pre-Commit Hook accessed!\n")
+	repo.ui.note('Pre-Commit Hook accessed!\n')
 	repo.ui.debug('kwargs = ',kwargs, "\n")
 	timestamp_mod(repo.ui, repo, **dict({'save': True, 'restore': None}))
 	kwargs['pats'].append(File_TimestampRecords)
 ''' # Hook_Pre_Commit is depreciated
 def Hook_Post_Status(repo, **kwargs):
-	repo.ui.note("TimestampMod|Post-Status Hook accessed!\n")
+	repo.ui.note('TimestampMod|Post-Status Hook accessed!\n')
+	myUnresolved = _check_Merge_unresolved(repo)
+	if myUnresolved:
+		repo.ui.note('TimestampMod|Post-Status Hook aborted - Unresolved merge detected!\n')
+		return
+	#end check for unresolved merged
 	timestamp_mod(repo.ui, repo, **dict({'save': None, 'restore': None}))
 
 def Hook_Update(repo, **kwargs):
-	repo.ui.note("TimestampMod|Hook_Update accessed!\n")
+	repo.ui.note('TimestampMod|Hook_Update accessed!\n')
 	if (len(repo.parents()) > 1):
-		repo.ui.status('TimestampMod|Hook_Update aborted - Merge in progress\n')
+		repo.ui.note('TimestampMod|Hook_Update aborted - Merge in progress\n')
 	else:
 		timestamp_mod(repo.ui, repo, **dict({'save': None, 'restore': True}))
 	#end of check for merging.
 
 def Hook_Post_Merge(repo, **kwargs):
-	repo.ui.note("TimestampMod|Post-Merge Hook accessed!\n")
-	#repo.ui.debug("Post-Merge:kwargs = \n", str(kwargs), '\n')
+	repo.ui.note('TimestampMod|Post-Merge Hook accessed!\n')
+	#repo.ui.debug('Post-Merge:kwargs = \n', str(kwargs), '\n')
+	myUnresolved = _check_Merge_unresolved(repo)
+	if myUnresolved:
+		repo.ui.note('TimestampMod|Post-Merge Hook aborted - Unresolved merge detected!\n')
+		return
+	#end check for unresolved merged
 	myPreview = False #starting value
 	if ('opts' in kwargs):
 		if ('preview' in kwargs['opts']):
 			myPreview = kwargs['opts']['preview']
 		#end of check for 'preview' option.
 	#end of check for 'opts' keyword.
-	if not myPreview:
+	if (not myPreview):
 		#only update timestamps if not just a preview.
 		timestamp_mod(repo.ui, repo, **dict({'save': None, 'restore': True}))
 	#check for preview option.
 
 def Hook_Post_Resolve(repo, **kwargs):
-	repo.ui.note("TimestampMod|Post-Resolve Hook accessed!\n")
-	#repo.ui.debug("Post-Resolve:kwargs = \n", str(kwargs), '\n')
+	repo.ui.note('TimestampMod|Post-Resolve Hook accessed!\n')
+	#repo.ui.debug('Post-Resolve:kwargs = \n', str(kwargs), '\n')
+	myUnresolved = _check_Merge_unresolved(repo)
+	if myUnresolved:
+		repo.ui.note('TimestampMod|Post-Resolve Hook aborted - Unresolved merge detected!\n')
+		return
+	#end check for unresolved merged
 	myResolveAll = False #starting value
 	if ('opts' in kwargs):
 		if ('all' in kwargs['opts']):
 			myResolveAll = kwargs['opts']['all']
-		#end of check for 'preview' option.
+		#end of check for 'all' option.
 	#end of check for 'opts' keyword.
 	if (myResolveAll or (File_TimestampRecords in str(kwargs['pats']))):
 		#Only re-apply timestamps if the timestamp file is the one being resolved.
 	https://bitbucket.org/tortoisehg/thg/issue/1347/add-support-for-pre-and-post-hooks
 	'''
 	repo.ui.note("TimestampMod|Post-Revert Hook accessed!\n")
-	repo.ui.debug("-----\nPost-Revert:kwargs = \n", str(kwargs), "\n-----\n")
+	#repo.ui.debug("-----\nPost-Revert:kwargs = \n", str(kwargs), "\n-----\n")
 	bDryRun = False #starting value
 	bAll = False #starting value
 	listExclude = list()
 		if (f_fileModTime>0):
 			# Valid timestamp detected!
 			# Display timestamp using local time adjustment.
-			repo.ui.status(time.strftime("%Y.%m.%d %H:%M:%S", time.localtime(f_fileModTime)), " \t", s_fileName, "\n")
+			repo.ui.note(time.strftime("%Y.%m.%d %H:%M:%S", time.localtime(f_fileModTime)), " \t", s_fileName, "\n")
 		else:
 			# No valid timestamp recorded, skip this file.
 			repo.ui.debug(s_fileName, ' - skipped - no timestamp recorded\n')
 #_ end of _display_Timestamps _________________________________________________
 
 
-
+#==============================================================================
+# _check_Merge_unresolved Function Definition
+#------------------------------------------------------------------------------
+# Summary: Check the repository's MergeState to see if there are any unresolved
+# files and return True if any unresolved files are found (False otherwise).
+#==============================================================================
+def _check_Merge_unresolved(repo):
+	'''Determine if there are unresolved files after a merge.'''
+	repo.ui.debug('...checking for unresolved files...\n')
+	localms = mergemod.mergestate(repo)
+	for testfile in localms:
+		if (localms[testfile] == 'u'):
+			repo.ui.debug('Unresolved merge conflicts found!\n')
+			return True
+	#end of loop through mergestate files
+	return False #will get to here if no unresolved files.
+#_ end of _check_Merge_unresolved _____________________________________________
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.