mirror of
				https://github.com/mnauw/git-remote-hg.git
				synced 2025-11-02 17:45:48 +01:00 
			
		
		
		
	Compare commits
	
		
			222 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					8c08b6de21 | ||
| 
						 | 
					949345fb11 | ||
| 
						 | 
					0d49f75131 | ||
| 
						 | 
					7159e4a030 | ||
| 
						 | 
					cdcd70b453 | ||
| 
						 | 
					f5c38f3a59 | ||
| 
						 | 
					3b11156e69 | ||
| 
						 | 
					afc1f3a2c2 | ||
| 
						 | 
					e596a5f457 | ||
| 
						 | 
					ec654d4682 | ||
| 
						 | 
					7913920a97 | ||
| 
						 | 
					da60201ae3 | ||
| 
						 | 
					704869df29 | ||
| 
						 | 
					5769e965eb | ||
| 
						 | 
					1ee28bd233 | ||
| 
						 | 
					1796289df3 | ||
| 
						 | 
					929ae262f5 | ||
| 
						 | 
					4328aa1c19 | ||
| 
						 | 
					919678be4a | ||
| 
						 | 
					ac8f659620 | ||
| 
						 | 
					28ed63b707 | ||
| 
						 | 
					dc91c58e1c | ||
| 
						 | 
					46178f546a | ||
| 
						 | 
					4c0e8e6439 | ||
| 
						 | 
					59b5a8c848 | ||
| 
						 | 
					be2445963b | ||
| 
						 | 
					8b4bfe7e87 | ||
| 
						 | 
					741b440fcc | ||
| 
						 | 
					03b1ac9845 | ||
| 
						 | 
					f3a8546406 | ||
| 
						 | 
					ccc9e55b7e | ||
| 
						 | 
					b516aa9326 | ||
| 
						 | 
					08626200d0 | ||
| 
						 | 
					b60eb47173 | ||
| 
						 | 
					76162ce148 | ||
| 
						 | 
					7ae03f7640 | ||
| 
						 | 
					95da53badd | ||
| 
						 | 
					a0608664ca | ||
| 
						 | 
					9d6d135855 | ||
| 
						 | 
					60a6c7b36d | ||
| 
						 | 
					74d1aa14ac | ||
| 
						 | 
					1d85449b0b | ||
| 
						 | 
					fe8b8c1a61 | ||
| 
						 | 
					510441bba9 | ||
| 
						 | 
					fa3484e08b | ||
| 
						 | 
					d1544e2ccd | ||
| 
						 | 
					153a216f47 | ||
| 
						 | 
					b3cdbe8e96 | ||
| 
						 | 
					d11509cab7 | ||
| 
						 | 
					4d01165b1b | ||
| 
						 | 
					a030d603ac | ||
| 
						 | 
					3d4a5a6d7e | ||
| 
						 | 
					7fb9d9b642 | ||
| 
						 | 
					fad59f53eb | ||
| 
						 | 
					e17e147fb1 | ||
| 
						 | 
					4878023a8b | ||
| 
						 | 
					0dfae24d21 | ||
| 
						 | 
					c7dbb5612b | ||
| 
						 | 
					cc4e5659d9 | ||
| 
						 | 
					2c993b3433 | ||
| 
						 | 
					4944a384cd | ||
| 
						 | 
					f29c42c645 | ||
| 
						 | 
					7b7c65f72d | ||
| 
						 | 
					cee3ed7c00 | ||
| 
						 | 
					01c9a981c7 | ||
| 
						 | 
					d0a5888580 | ||
| 
						 | 
					a5dfc9025b | ||
| 
						 | 
					4d337cff06 | ||
| 
						 | 
					5cc271ef18 | ||
| 
						 | 
					c8fff2cd06 | ||
| 
						 | 
					c95fba3c18 | ||
| 
						 | 
					aaef56a2a3 | ||
| 
						 | 
					a16c69a99c | ||
| 
						 | 
					00e95fd8df | ||
| 
						 | 
					5bf7aad6e3 | ||
| 
						 | 
					9b8e0ec2c0 | ||
| 
						 | 
					b309562574 | ||
| 
						 | 
					e25d3d78cd | ||
| 
						 | 
					ed5a70706a | ||
| 
						 | 
					0faf2c9189 | ||
| 
						 | 
					ada49422a7 | ||
| 
						 | 
					580cea0d31 | ||
| 
						 | 
					1f376e437f | ||
| 
						 | 
					4108665799 | ||
| 
						 | 
					fc28115a53 | ||
| 
						 | 
					e3009683f8 | ||
| 
						 | 
					54cec85f94 | ||
| 
						 | 
					5ad322c54d | ||
| 
						 | 
					13bbc8a342 | ||
| 
						 | 
					673b50d3f4 | ||
| 
						 | 
					35ecb45fda | ||
| 
						 | 
					1456e68129 | ||
| 
						 | 
					de95133416 | ||
| 
						 | 
					e0b752be8f | ||
| 
						 | 
					f050de1bcc | ||
| 
						 | 
					0bf3db826b | ||
| 
						 | 
					3698638e98 | ||
| 
						 | 
					765f9ae287 | ||
| 
						 | 
					5ddcdd33ec | ||
| 
						 | 
					435373ee83 | ||
| 
						 | 
					5e96683f67 | ||
| 
						 | 
					144f48df44 | ||
| 
						 | 
					ad36a25064 | ||
| 
						 | 
					679e016943 | ||
| 
						 | 
					9f6c541a2c | ||
| 
						 | 
					476ffcbde0 | ||
| 
						 | 
					76be528c0d | ||
| 
						 | 
					6c2f4d8ff4 | ||
| 
						 | 
					e9c37f78d8 | ||
| 
						 | 
					dfa6910cab | ||
| 
						 | 
					2ab9ae9073 | ||
| 
						 | 
					f21923b052 | ||
| 
						 | 
					45866dbeba | ||
| 
						 | 
					eaa9361ab0 | ||
| 
						 | 
					f0e4c95bf5 | ||
| 
						 | 
					e467b22dd3 | ||
| 
						 | 
					40c9eafcc9 | ||
| 
						 | 
					0bfbc0da4b | ||
| 
						 | 
					a1ca279d92 | ||
| 
						 | 
					e19dd84571 | ||
| 
						 | 
					1d94ba2d42 | ||
| 
						 | 
					85b585b824 | ||
| 
						 | 
					e8c88c70d9 | ||
| 
						 | 
					a35f93cbc1 | ||
| 
						 | 
					a59e1246a2 | ||
| 
						 | 
					cbbbaddc41 | ||
| 
						 | 
					5d429d2da1 | ||
| 
						 | 
					94bb2488e8 | ||
| 
						 | 
					e759d5232d | ||
| 
						 | 
					af96a84c98 | ||
| 
						 | 
					2ce962c5ab | ||
| 
						 | 
					8ac5532eb1 | ||
| 
						 | 
					9528e757d3 | ||
| 
						 | 
					628c45a4a9 | ||
| 
						 | 
					55689eb0a8 | ||
| 
						 | 
					7be9bf3db4 | ||
| 
						 | 
					20e923cf91 | ||
| 
						 | 
					a7ea76788c | ||
| 
						 | 
					5999a10519 | ||
| 
						 | 
					0853bc0230 | ||
| 
						 | 
					b3fccddd9f | ||
| 
						 | 
					7f99aa2565 | ||
| 
						 | 
					63c742e4a6 | ||
| 
						 | 
					6cff0327aa | ||
| 
						 | 
					5acd0028b4 | ||
| 
						 | 
					4f910f65d9 | ||
| 
						 | 
					7d82847d52 | ||
| 
						 | 
					37cd2f24ac | ||
| 
						 | 
					585e36edb9 | ||
| 
						 | 
					dd08e25665 | ||
| 
						 | 
					5905eb2231 | ||
| 
						 | 
					ebdd2f32ab | ||
| 
						 | 
					f8709175bf | ||
| 
						 | 
					38741e0bbf | ||
| 
						 | 
					e2f68018cd | ||
| 
						 | 
					e62984edde | ||
| 
						 | 
					7b53adef7b | ||
| 
						 | 
					858ca2c68a | ||
| 
						 | 
					093cb8ba94 | ||
| 
						 | 
					cd742bee40 | ||
| 
						 | 
					1d0c78eebc | ||
| 
						 | 
					8e81bc8515 | ||
| 
						 | 
					bd2e030cb0 | ||
| 
						 | 
					410e0d74ec | ||
| 
						 | 
					93dd913590 | ||
| 
						 | 
					418af65bf0 | ||
| 
						 | 
					d7db83bd2c | ||
| 
						 | 
					3ea455e7e7 | ||
| 
						 | 
					fd210eb002 | ||
| 
						 | 
					b852ee18b2 | ||
| 
						 | 
					c3f02d39ad | ||
| 
						 | 
					822c6e4b03 | ||
| 
						 | 
					b6e9475918 | ||
| 
						 | 
					517ceb91ac | ||
| 
						 | 
					114804f0cb | ||
| 
						 | 
					b022367aef | ||
| 
						 | 
					18626d346f | ||
| 
						 | 
					b81ec14c2e | ||
| 
						 | 
					1e279075dc | ||
| 
						 | 
					02a0a59a4b | ||
| 
						 | 
					185852eac4 | ||
| 
						 | 
					29a0d8a0e3 | ||
| 
						 | 
					aa528c9649 | ||
| 
						 | 
					018aa4753b | ||
| 
						 | 
					f173208406 | ||
| 
						 | 
					e7df347fab | ||
| 
						 | 
					0de8aa91f4 | ||
| 
						 | 
					22d9794c11 | ||
| 
						 | 
					f53a8653ab | ||
| 
						 | 
					b4c63539f2 | ||
| 
						 | 
					38070007aa | ||
| 
						 | 
					fadd5f698b | ||
| 
						 | 
					1eb8fa4805 | ||
| 
						 | 
					19f31c1c84 | ||
| 
						 | 
					ff221de459 | ||
| 
						 | 
					179fefda96 | ||
| 
						 | 
					c226ba3904 | ||
| 
						 | 
					776e36c147 | ||
| 
						 | 
					5b6d5283cb | ||
| 
						 | 
					5738ee42d8 | ||
| 
						 | 
					1d27390dd0 | ||
| 
						 | 
					cad5c95465 | ||
| 
						 | 
					259838a342 | ||
| 
						 | 
					55bbd81a75 | ||
| 
						 | 
					8db5b9a537 | ||
| 
						 | 
					bbc4009acf | ||
| 
						 | 
					c84feb364b | ||
| 
						 | 
					990152c0c8 | ||
| 
						 | 
					6ba42cdf98 | ||
| 
						 | 
					ef00e40d7c | ||
| 
						 | 
					1c72617831 | ||
| 
						 | 
					184551c71d | ||
| 
						 | 
					32d4f36f22 | ||
| 
						 | 
					ccb3f13d69 | ||
| 
						 | 
					2958556bec | ||
| 
						 | 
					4ea2fa76b3 | ||
| 
						 | 
					84b8b482a4 | ||
| 
						 | 
					978314a4be | ||
| 
						 | 
					51eabd4a17 | ||
| 
						 | 
					98c3535c3f | ||
| 
						 | 
					3abf376e9e | ||
| 
						 | 
					0b71ca38e7 | 
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					/build/
 | 
				
			||||||
 | 
					/dist/
 | 
				
			||||||
 | 
					/git_remote_hg.egg-info/
 | 
				
			||||||
							
								
								
									
										20
									
								
								.travis.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								.travis.yml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					dist: xenial
 | 
				
			||||||
 | 
					language: minimal
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cache:
 | 
				
			||||||
 | 
					  directories:
 | 
				
			||||||
 | 
					    - $HOME/.cache/git-remote-hg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					script:
 | 
				
			||||||
 | 
					  - ./tools/check-versions hg:$HG_VERSION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					matrix:
 | 
				
			||||||
 | 
					  include:
 | 
				
			||||||
 | 
					    - env:
 | 
				
			||||||
 | 
					    - env: HG_VERSION=@
 | 
				
			||||||
 | 
					    - env: HG_VERSION=5.0
 | 
				
			||||||
 | 
					    - env: HG_VERSION=4.9
 | 
				
			||||||
 | 
					    - env: HG_VERSION=4.8
 | 
				
			||||||
 | 
					    - env: HG_VERSION=4.7
 | 
				
			||||||
 | 
					    - env: HG_VERSION=4.6
 | 
				
			||||||
 | 
					    - env: HG_VERSION=4.5
 | 
				
			||||||
							
								
								
									
										62
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										62
									
								
								Makefile
									
									
									
									
									
								
							@@ -1,6 +1,64 @@
 | 
				
			|||||||
all:
 | 
					prefix := $(HOME)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bindir := $(prefix)/bin
 | 
				
			||||||
 | 
					mandir := $(prefix)/share/man/man1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					all: build doc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					build:
 | 
				
			||||||
 | 
						if [ -n "$$PYTHON" ] && "$$PYTHON" -c 'import mercurial' 2> /dev/null ; then \
 | 
				
			||||||
 | 
							: Use chosen Python version ; \
 | 
				
			||||||
 | 
						elif python3 -c 'import mercurial' 2> /dev/null ; then \
 | 
				
			||||||
 | 
							PYTHON=python3 ; \
 | 
				
			||||||
 | 
						elif python2 -c 'import mercurial' 2> /dev/null ; then \
 | 
				
			||||||
 | 
							PYTHON=python2 ; \
 | 
				
			||||||
 | 
						elif python -c 'import mercurial' 2> /dev/null ; then \
 | 
				
			||||||
 | 
							PYTHON=python ; \
 | 
				
			||||||
 | 
						fi ; \
 | 
				
			||||||
 | 
						if [ -n "$$PYTHON" ] ; then \
 | 
				
			||||||
 | 
							PYTHON=python ; \
 | 
				
			||||||
 | 
						fi ; \
 | 
				
			||||||
 | 
						mkdir -p bin ; \
 | 
				
			||||||
 | 
						for s in git-remote-hg git-hg-helper ; do \
 | 
				
			||||||
 | 
							printf "%s\n" "#!/usr/bin/env $$PYTHON" > "bin/$$s" ; \
 | 
				
			||||||
 | 
							tail -n +2 "./$$s" >> "bin/$$s" ; \
 | 
				
			||||||
 | 
							chmod 755 "bin/$$s" ; \
 | 
				
			||||||
 | 
							touch -r "./$$s" "bin/$$s" ; \
 | 
				
			||||||
 | 
						done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					doc: doc/git-remote-hg.1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test:
 | 
					test:
 | 
				
			||||||
	$(MAKE) -C test
 | 
						$(MAKE) -C test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.PHONY: all test
 | 
					doc/git-remote-hg.1: doc/git-remote-hg.txt
 | 
				
			||||||
 | 
						a2x -d manpage -f manpage $<
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					clean:
 | 
				
			||||||
 | 
						$(RM) doc/git-remote-hg.1
 | 
				
			||||||
 | 
						$(RM) -r bin/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					D = $(DESTDIR)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					install: build
 | 
				
			||||||
 | 
						install -d -m 755 $(D)$(bindir)/
 | 
				
			||||||
 | 
						install -m 755 bin/git-remote-hg $(D)$(bindir)/git-remote-hg
 | 
				
			||||||
 | 
						install -m 755 bin/git-hg-helper $(D)$(bindir)/git-hg-helper
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					install-doc: doc
 | 
				
			||||||
 | 
						install -d -m 755 $(D)$(mandir)/
 | 
				
			||||||
 | 
						install -m 644 doc/git-remote-hg.1 $(D)$(mandir)/git-remote-hg.1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pypi:
 | 
				
			||||||
 | 
						version=`git describe --tags ${REV}` && \
 | 
				
			||||||
 | 
							sed -i "s/version = .*/version = '$$version'[1:]/" setup.py
 | 
				
			||||||
 | 
						-rm -rf dist build
 | 
				
			||||||
 | 
						python setup.py sdist bdist_wheel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pypi-upload:
 | 
				
			||||||
 | 
						twine upload dist/*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pypi-test:
 | 
				
			||||||
 | 
						twine upload --repository-url https://test.pypi.org/legacy/ dist/*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.PHONY: all build test install install-doc clean pypy pypy-upload
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										419
									
								
								README.asciidoc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										419
									
								
								README.asciidoc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,419 @@
 | 
				
			|||||||
 | 
					'git-remote-hg' is the semi-official Mercurial bridge from Git project, once
 | 
				
			||||||
 | 
					installed, it allows you to clone, fetch and push to and from Mercurial
 | 
				
			||||||
 | 
					repositories as if they were Git ones:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					git clone "hg::http://selenic.com/repo/hello"
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To enable this, simply add the 'git-remote-hg' script anywhere in your `$PATH`:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					wget https://raw.github.com/mnauw/git-remote-hg/master/git-remote-hg -O ~/bin/git-remote-hg
 | 
				
			||||||
 | 
					chmod +x ~/bin/git-remote-hg
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In Windows, you also need to put and an NTFS symbolic link named `python2.exe` somewhere
 | 
				
			||||||
 | 
					on your `$PATH` pointing to your Python 2 executable:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					mklink <path to link> <path to python.exe>
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					That's it :)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Obviously you will need Mercurial installed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					****
 | 
				
			||||||
 | 
					At present, this "working copy"/fork <<add-features, adds the following features>>
 | 
				
			||||||
 | 
					(and I would prefer it is indeed rather a "working copy"
 | 
				
			||||||
 | 
					to be appropriately merged upstream):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* eliminates a number of <<limitations, limitations>> as mentioned below
 | 
				
			||||||
 | 
					* properly annotates copy/rename when pushing new commits to Mercurial
 | 
				
			||||||
 | 
					* adds a 'git-hg-helper' script than can aid in the git-hg interaction workflow
 | 
				
			||||||
 | 
					* provides enhanced bidirectional git-hg safety
 | 
				
			||||||
 | 
					* avoids clutter of `refs/hg/...` by keeping these implementation details really private
 | 
				
			||||||
 | 
					* more robust and efficient fetching, especially so when fetching or cloning from multiple
 | 
				
			||||||
 | 
					  Mercurial clones which will only process changesets not yet fetched from elsewhere
 | 
				
			||||||
 | 
					  (as opposed to processing everything all over again)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					See sections below or sidemarked notes for more details.
 | 
				
			||||||
 | 
					****
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					== Configuration ==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you want to see Mercurial revisions as Git commit notes:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					% git config core.notesRef refs/notes/hg
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you are not interested in Mercurial permanent and global branches (aka. commit labels):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					% git config --global remote-hg.track-branches false
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					With this configuration, the 'branches/foo' refs won't appear.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you want the equivalent of 'hg clone --insecure':
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					% git config --global remote-hg.insecure true
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you want 'git-remote-hg' to be compatible with 'hg-git', and generate exactly the same commits:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					% git config --global remote-hg.hg-git-compat true
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					== Notes ==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Remember to run `git gc --aggressive` after cloning a repository, specially if
 | 
				
			||||||
 | 
					it's a big one. Otherwise lots of space will be wasted.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The oldest version of mercurial supported is 1.9. For the most part 1.8 works,
 | 
				
			||||||
 | 
					but you might experience some issues.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=== Pushing branches ===
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To push a branch, you need to use the "branches/" prefix:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					% git checkout branches/next
 | 
				
			||||||
 | 
					# do stuff
 | 
				
			||||||
 | 
					% git push origin branches/next
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					All the pushed commits will receive the "next" Mercurial named branch.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					*Note*: Make sure you don't have +remote-hg.track-branches+ disabled.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=== Cloning HTTPS ===
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The simplest way is to specify the user and password in the URL:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					git clone hg::https://user:password@bitbucket.org/user/repo
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You can also use the http://mercurial.selenic.com/wiki/SchemesExtension[schemes extension]:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					[auth]
 | 
				
			||||||
 | 
					bb.prefix = https://bitbucket.org/user/
 | 
				
			||||||
 | 
					bb.username = user
 | 
				
			||||||
 | 
					bb.password = password
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Finally, you can also use the
 | 
				
			||||||
 | 
					https://pypi.python.org/pypi/mercurial_keyring[keyring extension].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					However, some of these features require very new versions of 'git-remote-hg',
 | 
				
			||||||
 | 
					so you might have better luck simply specifying the username and password in
 | 
				
			||||||
 | 
					the URL.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=== Submodules ===
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Hg repositories can be used as git submodule, but this requires to allow the hg procotol to be used by git submodule commands:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					git config protocol.hg.allow always
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Or adding manually the following to your git configuration file:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					[protocol "hg"]
 | 
				
			||||||
 | 
					        allow = always
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This can be done per-repository, every time after a clone, or globally in the global .gitconfig (using the --global command-line option).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=== Caveats ===
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The only major incompatibility is that Git octopus merges (a merge with more
 | 
				
			||||||
 | 
					than two parents) are not supported.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Mercurial branches and bookmarks have some limitations of Git branches: you
 | 
				
			||||||
 | 
					can't have both 'dev/feature' and 'dev' (as Git uses files and directories to
 | 
				
			||||||
 | 
					store them).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Multiple anonymous heads (which are useless anyway) are not supported; you
 | 
				
			||||||
 | 
					would only see the latest head.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Closed branches are not supported; they are not shown and you can't close or
 | 
				
			||||||
 | 
					reopen. Additionally in certain rare situations a synchronization issue can
 | 
				
			||||||
 | 
					occur (https://github.com/felipec/git/issues/65[Bug #65]).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[limitations]]
 | 
				
			||||||
 | 
					Limitations of the remote-helpers' framework apply. In particular, these
 | 
				
			||||||
 | 
					commands don't work:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* `git push origin :branch-to-delete`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					****
 | 
				
			||||||
 | 
					Another limitation is that if `git log` reports a rename, this will not survive
 | 
				
			||||||
 | 
					the push and Mercurial will not be aware of a rename (and similarly so for copy).
 | 
				
			||||||
 | 
					Though Mercurial would know about it if you *manually* ran `git-format-patch`
 | 
				
			||||||
 | 
					followed by a `hg apply -s`, which is not the nice way to go obviously.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Actually, scratch the limitations above ascribed to the remote-helpers framework.
 | 
				
			||||||
 | 
					They are not limitations of the framework, but are due to how the original
 | 
				
			||||||
 | 
					implementation of 'git-remote-hg' interacts with it.
 | 
				
			||||||
 | 
					Using the remote-helpers framework in only a slightly different way has none
 | 
				
			||||||
 | 
					of the above limitations.  See the <<no-limitations, relevant section>>
 | 
				
			||||||
 | 
					below for more details.
 | 
				
			||||||
 | 
					****
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					== Other projects ==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					There are other 'git-remote-hg' projects out there, do not confuse this one,
 | 
				
			||||||
 | 
					this is the one distributed officially by the Git project
 | 
				
			||||||
 | 
					(_though actually no longer so nowadays_):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* https://github.com/msysgit/msysgit/wiki/Guide-to-git-remote-hg[msysgit's git-remote-hg]
 | 
				
			||||||
 | 
					* https://github.com/rfk/git-remote-hg[rfk's git-remote-hg]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For a comparison between these and other projects go
 | 
				
			||||||
 | 
					https://github.com/felipec/git/wiki/Comparison-of-git-remote-hg-alternatives[here].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[no-limitations]]
 | 
				
			||||||
 | 
					== Limitations (or not) ==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If interested in some of technical details behind this explanation, then also
 | 
				
			||||||
 | 
					see the relevant section in 'git-remote-hg' manpage.  Otherwise, the general
 | 
				
			||||||
 | 
					idea is presented here.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					More precisely and simply, the <<limitations, mentioned limitations>> are indeed
 | 
				
			||||||
 | 
					limitations of the `export` capability of
 | 
				
			||||||
 | 
					https://www.kernel.org/pub/software/scm/git/docs/gitremote-helpers.html[gitremote-helpers(1)]
 | 
				
			||||||
 | 
					framework.  However, the framework also supports a `push` capability and when this
 | 
				
			||||||
 | 
					is used appropriately in the remote helper the aforementioned limitations do not apply.
 | 
				
			||||||
 | 
					In the case of `export` capability, git-core will internally invoke `git-fast-export`
 | 
				
			||||||
 | 
					and the helper will process this data and hand over generated changesets to Mercurial.
 | 
				
			||||||
 | 
					In the case of `push` capability, git informs the helper what (refs) should go where,
 | 
				
			||||||
 | 
					and the helper is free to ponder about this and take the required action, such as
 | 
				
			||||||
 | 
					to invoke `git-fast-export` itself (with suitable options) and process its output
 | 
				
			||||||
 | 
					the same way as before (and over to Mercurial).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					And so;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* `git push origin :branch-to-delete` will delete the bookmark `branch-to-delete` on remote
 | 
				
			||||||
 | 
					* `git push --dry-run origin branch` will not touch the remote
 | 
				
			||||||
 | 
					(or any local state, except for local helper proxy repo)
 | 
				
			||||||
 | 
					* `git push origin old:new` will push `old` onto `new` in the remote
 | 
				
			||||||
 | 
					* `git push origin <history-with-copy/rename>` will push copy/rename aware Mercurial revisions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To tweak how 'git-remote-hg' decides on a copy/rename, use e.g:
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					% git config --global remote-hg.fast-export-options '-M -C -C'
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[add-features]]
 | 
				
			||||||
 | 
					== Additional Features ==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=== Miscellaneous Tweaks ===
 | 
				
			||||||
 | 
					Other than <<no-limitations, removing the limitations>> as mentioned above,
 | 
				
			||||||
 | 
					a number of issues (either so reported in
 | 
				
			||||||
 | 
					https://github.com/felipec/git-remote-hg/issues[issue tracking] or not) have been
 | 
				
			||||||
 | 
					addressed here, e.g. notes handling, `fetch --prune` support, correctly fetching
 | 
				
			||||||
 | 
					after a `strip` on remote repo, tracking remote changes to import (if any) in a
 | 
				
			||||||
 | 
					safe, robust and efficient way, etc.  Some of these have been highlighted above.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For example, the `refs/hg/...` refs are really an implementation detail
 | 
				
			||||||
 | 
					that need not clutter up the (visible) ref space.  So, in as much as they
 | 
				
			||||||
 | 
					are still relevant, these are now kept elsewhere out of sight.
 | 
				
			||||||
 | 
					If somehow your workflow relies on having these in the old place:
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					% git config --global remote-hg.show-private-refs true
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					More importantly, a significantly more efficient workflow is achieved using
 | 
				
			||||||
 | 
					one set of shared marks files for all remotes (which also forces a local repo
 | 
				
			||||||
 | 
					to use an internal proxy clone).
 | 
				
			||||||
 | 
					The practical consequence is that fetching from a newly added remote hg repo
 | 
				
			||||||
 | 
					does not require another (lengthy) complete import
 | 
				
			||||||
 | 
					(as the original clone) but will only fetch additional changesets (if any).
 | 
				
			||||||
 | 
					The same goes for subsequent fetching from any hg remote; what was fetched
 | 
				
			||||||
 | 
					and imported from some remote need not be imported again from another.
 | 
				
			||||||
 | 
					Operating in this shared mode also has the added advantage
 | 
				
			||||||
 | 
					of correctly pushing after a `strip` on a remote.
 | 
				
			||||||
 | 
					This shared-marks-files behaviour is the default on a fresh repo clone.  It can
 | 
				
			||||||
 | 
					also be enabled on an existing one by the following setting.
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					% git config --global remote-hg.shared-marks true
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					Note, however, that one should then perform a fetch from each relevant remote
 | 
				
			||||||
 | 
					to fully complete the conversion (prior to subsequent pushing).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Some Mercurial names (of branches, bookmarks, tags) may not be a valid git
 | 
				
			||||||
 | 
					refname. See e.g. `man git-check-ref-format` for a rather involved set of rules.
 | 
				
			||||||
 | 
					Moreover, while a slash `/` is allowed, it is not supported to have both a `parent`
 | 
				
			||||||
 | 
					and `parent/child` branch (though only the latter is allowed). Even though
 | 
				
			||||||
 | 
					it is not quite (bidirectionally) safe, a (percentage) URL encoding
 | 
				
			||||||
 | 
					(with some additional twist) is performed to obtain sane git refnames, at least
 | 
				
			||||||
 | 
					so for most cases.  If some nasty cases still slip through, then likely only
 | 
				
			||||||
 | 
					a few instances (out of a whole Mercurial repo) are
 | 
				
			||||||
 | 
					problematic.  This could be handled by a single-branch clone and/or configuring
 | 
				
			||||||
 | 
					a suitable refspec.  However, it might be more convenient to simply filter out a
 | 
				
			||||||
 | 
					few unimportant pesky cases, which can be done by configuring a regural
 | 
				
			||||||
 | 
					expression in following setting:
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					% git config remote-hg.ignore-name nasty/nested/name
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					Recall also that a config setting can be provided at clone time
 | 
				
			||||||
 | 
					(command line using `--config` option).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					% git config --global remote-hg.remove-username-quotes false
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					By default, for backwards compatibility with earlier versions,
 | 
				
			||||||
 | 
					git-remote-hg removes quotation marks from git usernames
 | 
				
			||||||
 | 
					(e.g. 'Raffaello "Raphael" Sanzio da Urbino <raphael@example.com>'
 | 
				
			||||||
 | 
					would become 'Raffaello Raphael Sanzio da Urbino
 | 
				
			||||||
 | 
					<raphael@example.com>').  This breaks round-trip compatibility; a git
 | 
				
			||||||
 | 
					commit by an author with quotes would become an hg commit without,
 | 
				
			||||||
 | 
					and if re-imported into git, would get a different SHA1.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To restore round-trip compatibility (at the cost of backwards
 | 
				
			||||||
 | 
					compatibility with commits converted by older versions of
 | 
				
			||||||
 | 
					git-remote-hg), turn 'remote-hg.remove-username-quotes' off.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=== Helper Commands ===
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Beyond that, a 'git-hg-helper' script has been added that can aid in the git-hg
 | 
				
			||||||
 | 
					interaction workflow with a number of subcommands that are not in the purview of
 | 
				
			||||||
 | 
					a remote helper.  This is similar to e.g. 'git-svn' being a separate program
 | 
				
			||||||
 | 
					altogether.  These subcommands
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* provide conversion from a hg changeset id to a git commit hash, or vice versa
 | 
				
			||||||
 | 
					* provide consistency and cleanup maintenance on internal `git-remote-hg` metadata marks
 | 
				
			||||||
 | 
					* provide optimization of git marks of a fetch-only remote
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					See the helper script commands' help description for further details.
 | 
				
			||||||
 | 
					It should simply be installed (`$PATH` accessible) next to 'git-remote-hg'.
 | 
				
			||||||
 | 
					Following git alias is probably also convenient as it allows invoking the helper
 | 
				
			||||||
 | 
					as `git hg`:
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					% git config --global alias.hg '!git-hg-helper'
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					With that in place, running `git hg gc <remote>` after initial fetch from (large)
 | 
				
			||||||
 | 
					<remote> will save quite some space in the git marks file.  Not to mention some time
 | 
				
			||||||
 | 
					each time it is loaded and saved again (upon fetch).  If the remote is ever pushed
 | 
				
			||||||
 | 
					to, the marks file will similarly be squashed, but for a fetch-only <remote>
 | 
				
			||||||
 | 
					the aforementioned command will do.  It may also be needed to run aforementioned
 | 
				
			||||||
 | 
					command after a `git gc` has been performed.  You will notice the need
 | 
				
			||||||
 | 
					when `git-fast-import` or `git-fast-export` complain about not finding objects ;-)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In addition, the helper also provides support routines for `git-remote-hg` that
 | 
				
			||||||
 | 
					provide for increased (or at least safer) git-hg bidirectionality.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Before explaining how it helps, let's first elaborate on what is really
 | 
				
			||||||
 | 
					meant by the above _bidirectionality_ since it can be regarded in 2 directions.
 | 
				
			||||||
 | 
					From the git repo point of view, one can push to a hg repo and then fetch (or
 | 
				
			||||||
 | 
					clone) back to git. Or one could have fetched a changeset from some hg repo and
 | 
				
			||||||
 | 
					then push this back to (another) hg clone.  So what happens in either case? In the
 | 
				
			||||||
 | 
					former case, from git to hg and then back, things work out ok whether or not in
 | 
				
			||||||
 | 
					hg-git compatibility mode.  In the latter case, it is very likely (but
 | 
				
			||||||
 | 
					ultimately not guaranteed) that it works out in hg-git compatibility mode, and far
 | 
				
			||||||
 | 
					less likely otherwise.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Most approaches on bidirectionality try to go for the "mapping" way.
 | 
				
			||||||
 | 
					That is, find a way to map all Mercurial (meta)data somewhere into git;
 | 
				
			||||||
 | 
					in the commit message, or in non-standard ways in extra headers in commit objects
 | 
				
			||||||
 | 
					(e.g. the latest hg-git approach).  The upside of this is that such a git repo can be
 | 
				
			||||||
 | 
					cloned to another git repo, and then one can push back into hg which will/should
 | 
				
			||||||
 | 
					turn out ok.  The downside is setting up such a mapping in the first place,
 | 
				
			||||||
 | 
					avoiding the slightest error in translating authors, timestamps etc,
 | 
				
			||||||
 | 
					and maintaining all that whenever there is some Mercurial API/ABI breakage.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The approach here is to consider a typical git-hg interaction workflow and to
 | 
				
			||||||
 | 
					ensure simple/safe bidirectionality in such a setting.  That is, you are (obviously)
 | 
				
			||||||
 | 
					in a situation having to deal with some Mercurial repo and quite probably
 | 
				
			||||||
 | 
					with various clones as well. The objective is to fetch from these repos/clones,
 | 
				
			||||||
 | 
					work in git and then push back.  And in the latter case, one needs to make sure
 | 
				
			||||||
 | 
					that hg changesets from one hg clone end up *exactly* that way in another hg
 | 
				
			||||||
 | 
					clone (or the git-hg bridge usage might not be so appreciated).  Such pushes are
 | 
				
			||||||
 | 
					probably not recommended workflow practice, but no accidents or issues should
 | 
				
			||||||
 | 
					arise from any push in these circumstances. There is less interest in this setting,
 | 
				
			||||||
 | 
					however, for (git-wise) cloning around the derived git repo.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Now, depending on your workflow and to ensure the above behaves well,
 | 
				
			||||||
 | 
					following setting can be enabled as preferred:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					% git config --global remote-hg.check-hg-commits fail
 | 
				
			||||||
 | 
					% git config --global remote-hg.check-hg-commits push
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If not set, the behaviour is as before; pushing a commit based on hg changeset
 | 
				
			||||||
 | 
					will again transform the latter into a new hg changeset which may or may not
 | 
				
			||||||
 | 
					match the original (as described above).
 | 
				
			||||||
 | 
					If set to `fail`, it will reject and abort the push.
 | 
				
			||||||
 | 
					If set to `push`, it will re-use the original changeset in a Mercurial native
 | 
				
			||||||
 | 
					way (rather than creating a new one).  The latter guarantees the changeset ends
 | 
				
			||||||
 | 
					up elsewhere as expected (regardless of conversion mapping or ABI).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Note that identifying and re-using the hg changeset relies on metadata
 | 
				
			||||||
 | 
					(`refs/notes/hg` and marks files) that is not managed or maintained by any
 | 
				
			||||||
 | 
					git-to-git fetch (or clone).
 | 
				
			||||||
 | 
					As such (and as said), this approach aims for plain-and-simple safety, but only
 | 
				
			||||||
 | 
					within a local scope (git repo).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=== Mercurial Subrepository Support ===
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Both Git and Mercurial support a submodule/subrepo system.
 | 
				
			||||||
 | 
					In case of Git, URLs are managed in `.gitmodules`, submodule state is tracked
 | 
				
			||||||
 | 
					in tree objects and only Git submodules are supported.
 | 
				
			||||||
 | 
					Mercurial manages URLs in `.hgsub`, records subrepo state in `.hgsubstate` and
 | 
				
			||||||
 | 
					supports Git, Mercurial and Subversion subrepos (at time of writing).
 | 
				
			||||||
 | 
					Merely the latter diversity in subrepo types shows that somehow mapping Mercurial
 | 
				
			||||||
 | 
					"natively" to git submodules is not quite evident.  Moreover, while one might
 | 
				
			||||||
 | 
					conceivably devise such a mapping restricted to git and hg subrepos, any such would
 | 
				
			||||||
 | 
					seem error-prone and fraught with all sorts of tricky cases and inconvenient
 | 
				
			||||||
 | 
					workflow handling (innovative robust suggestions are welcome though ...)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					So, rather than overtaking the plumbing and ending up with stuffed drain further on,
 | 
				
			||||||
 | 
					the approach here is (again) to keep it plain-and-simple.  That is, provide some
 | 
				
			||||||
 | 
					git-ish look-and-feel helper script commands for setting up and manipulating
 | 
				
			||||||
 | 
					subrepos.  And so (if the alias mentioned above has been defined), `git hg sub`
 | 
				
			||||||
 | 
					provides commands similar to `git submodule` that accomplish what is otherwise
 | 
				
			||||||
 | 
					taken care of by the Mercurial subrepo support.
 | 
				
			||||||
 | 
					The latter is obviously extended to be git-aware in that e.g. a Mercurial subrepo
 | 
				
			||||||
 | 
					is cloned as a git-hg subrepo and translation back-and-forth between hg changeset id
 | 
				
			||||||
 | 
					and git commit hash is also performed where needed.  There is no support though
 | 
				
			||||||
 | 
					for Subversion subrepos.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					As with the other commands, see the help description for the proper details,
 | 
				
			||||||
 | 
					but the following example session may clarify the principle:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					% git clone hg::hgparentrepo
 | 
				
			||||||
 | 
					# bring in subrepos in proper location:
 | 
				
			||||||
 | 
					% git hg sub update
 | 
				
			||||||
 | 
					# do some work
 | 
				
			||||||
 | 
					% git pull --rebase origin
 | 
				
			||||||
 | 
					# update subrepo state:
 | 
				
			||||||
 | 
					% git hg sub update
 | 
				
			||||||
 | 
					# do work in subrepo and push
 | 
				
			||||||
 | 
					% ( cd subrepo && git push origin HEAD:master )
 | 
				
			||||||
 | 
					# fetch to update refs/notes/hg (or enable remote-hg.push-updates-notes)
 | 
				
			||||||
 | 
					% ( cd subrepo && git fetch origin )
 | 
				
			||||||
 | 
					# update .hgsubstate to subrepo HEAD:
 | 
				
			||||||
 | 
					% git hg sub upstate
 | 
				
			||||||
 | 
					% git add .hgsubstate
 | 
				
			||||||
 | 
					# add more, commit and push as intended
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Note that the refspec `HEAD:master` is needed if working with detached `HEAD`
 | 
				
			||||||
 | 
					in subrepo, and that pushing such refspec is actually supported now in a git-hg subrepo
 | 
				
			||||||
 | 
					as explained <<no-limitations, earlier>>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					== Contributing ==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Please file an issue with some patches or a pull-request.
 | 
				
			||||||
							
								
								
									
										1
									
								
								doc/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								doc/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					git-remote-hg.1
 | 
				
			||||||
							
								
								
									
										5
									
								
								doc/SubmittingPatches
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								doc/SubmittingPatches
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					Please send your patches using `git format-patch` to the mailing list:
 | 
				
			||||||
 | 
					git-fc@googlegroups.com.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Make sure all the tests pass by running `make test`, and if possible add a new
 | 
				
			||||||
 | 
					test to exercise the code you are submitting.
 | 
				
			||||||
							
								
								
									
										211
									
								
								doc/git-remote-hg.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										211
									
								
								doc/git-remote-hg.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,211 @@
 | 
				
			|||||||
 | 
					git-remote-hg(1)
 | 
				
			||||||
 | 
					================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NAME
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					git-remote-hg - bidirectional bridge between Git and Mercurial
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SYNOPSIS
 | 
				
			||||||
 | 
					--------
 | 
				
			||||||
 | 
					[verse]
 | 
				
			||||||
 | 
					'git clone' hg::<hg repository>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DESCRIPTION
 | 
				
			||||||
 | 
					-----------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This tool allows you to transparently clone, fetch and push to and from Mercurial
 | 
				
			||||||
 | 
					repositories as if they were Git ones.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To use it you simply need to use the "'hg::'" prefix when specifying a remote URL
 | 
				
			||||||
 | 
					(e.g. when cloning).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EXAMPLE
 | 
				
			||||||
 | 
					-------
 | 
				
			||||||
 | 
					------------
 | 
				
			||||||
 | 
					$ git clone hg::http://selenic.com/repo/hello
 | 
				
			||||||
 | 
					------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CONFIGURATION
 | 
				
			||||||
 | 
					-------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you want to see Mercurial revisions as Git commit notes:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					% git config core.notesRef refs/notes/hg
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you are not interested in Mercurial permanent and global branches (aka. commit labels):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					% git config --global remote-hg.track-branches false
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					With this configuration, the 'branches/foo' refs won't appear.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you want the equivalent of `hg clone --insecure`:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					% git config --global remote-hg.insecure true
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you want 'git-remote-hg' to be compatible with 'hg-git', and generate exactly the same commits:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					% git config --global remote-hg.hg-git-compat true
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you would like (why?) the old behaviour (export capability)
 | 
				
			||||||
 | 
					where various limitations apply:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					% git config --global remote-hg.capability-push false
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In the new behaviour, performing a git push will make git search for and detect
 | 
				
			||||||
 | 
					file rename and copy and turn this into Mercurial commit metadata.  To tweak how this
 | 
				
			||||||
 | 
					detection happens, e.g. have it search even more:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					% git config --global remote-hg.fast-export-options '-M -C -C'
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The default otherwise is simply `-M -C`.  See also e.g.
 | 
				
			||||||
 | 
					https://www.kernel.org/pub/software/scm/git/docs/git-log.html[git-log(1) manpage]
 | 
				
			||||||
 | 
					for more details on the options used to tweak this.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					As the old refs/hg/... are actually an implementation detail, they are now
 | 
				
			||||||
 | 
					maintained not so visibly.  If that, however, would be preferred:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					% git config --global remote-hg.show-private-refs true
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Use of shared marks files is the default in a new repo, but can also be enabled
 | 
				
			||||||
 | 
					for an existing repo:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					% git config --global remote-hg.shared-marks true
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Note that one should perform a fetch from each remote to properly complete the
 | 
				
			||||||
 | 
					conversion to shared marks files.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Mercurial name(s) (of a branch or bookmark) that are not a valid git refname,
 | 
				
			||||||
 | 
					can be ignored by configuring a suitable regular expression, e.g. avoiding
 | 
				
			||||||
 | 
					the invalid '~'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					% git config --global remote-hg.ignore-name ~
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NOTES
 | 
				
			||||||
 | 
					-----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Remember to run `git gc --aggressive` after cloning a repository, specially if
 | 
				
			||||||
 | 
					it's a big one. Otherwise lots of space will be wasted.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The oldest version of Mercurial supported is 1.9. For the most part 1.8 works,
 | 
				
			||||||
 | 
					but you might experience some issues.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Pushing branches
 | 
				
			||||||
 | 
					~~~~~~~~~~~~~~~~
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To push a Mercurial named branch, you need to use the "branches/" prefix:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					% git checkout branches/next
 | 
				
			||||||
 | 
					# do stuff
 | 
				
			||||||
 | 
					% git push origin branches/next
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					All the pushed commits will receive the "next" Mercurial named branch.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					*Note*: Make sure you don't have +remote-hg.track-branches+ disabled.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Cloning HTTPS
 | 
				
			||||||
 | 
					~~~~~~~~~~~~~
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The simplest way is to specify the user and password in the URL:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					git clone hg::https://user:password@bitbucket.org/user/repo
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You can also use the http://mercurial.selenic.com/wiki/SchemesExtension[schemes extension]:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					[auth]
 | 
				
			||||||
 | 
					bb.prefix = https://bitbucket.org/user/
 | 
				
			||||||
 | 
					bb.username = user
 | 
				
			||||||
 | 
					bb.password = password
 | 
				
			||||||
 | 
					--------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Finally, you can also use the
 | 
				
			||||||
 | 
					https://pypi.python.org/pypi/mercurial_keyring[keyring extension].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CAVEATS
 | 
				
			||||||
 | 
					-------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The only major incompatibility is that Git octopus merges (a merge with more
 | 
				
			||||||
 | 
					than two parents) are not supported.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Mercurial branches and bookmarks have some limitations of Git branches: you
 | 
				
			||||||
 | 
					can't have both 'dev/feature' and 'dev' (as Git uses files and directories to
 | 
				
			||||||
 | 
					store them).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Multiple anonymous heads (which are useless anyway) are not supported; you
 | 
				
			||||||
 | 
					would only see the latest head.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Closed branches are not supported; they are not shown and you can't close or
 | 
				
			||||||
 | 
					reopen. Additionally in certain rare situations a synchronization issue can
 | 
				
			||||||
 | 
					occur (https://github.com/felipec/git/issues/65[Bug #65]).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TECHNICAL DISCUSSION
 | 
				
			||||||
 | 
					--------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					As `git-remote-hg` is a developer tool after all, it might be interesting to know a
 | 
				
			||||||
 | 
					bit about what is going on behind the scenes, without necessarily going into all the
 | 
				
			||||||
 | 
					details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					So let's first have a look in the `.git/hg` directory, which typically
 | 
				
			||||||
 | 
					contains a subdirectory for each remote Mercurial repo alias, as well as a `.hg`
 | 
				
			||||||
 | 
					subdirectory.  If the Mercurial repo is a local one, it will (again typically)
 | 
				
			||||||
 | 
					only contain a `marks-git` and a `marks-hg` file.  If the repo is a remote one,
 | 
				
			||||||
 | 
					then the `clone` contains, well, a local clone of the remote.  However, all
 | 
				
			||||||
 | 
					these clones share storage through the `.hg` directory mentioned previously (so
 | 
				
			||||||
 | 
					they do not add up separately). During a fetch/push, the local (proxy) repo is
 | 
				
			||||||
 | 
					used as an intermediate stage. If you would also prefer such an intermediate
 | 
				
			||||||
 | 
					stage for local repos, then setting the environment variable
 | 
				
			||||||
 | 
					`GIT_REMOTE_HG_TEST_REMOTE` will also use a proxy repo clone for a local repo.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					As for the marks files, `marks-git` is created and used by `git-fast-export`
 | 
				
			||||||
 | 
					and `git-fast-import` and contains a mapping from mark to commit hash, where a
 | 
				
			||||||
 | 
					mark is essentially a plain number.  `marks-hg` similarly contains a (JSON) based
 | 
				
			||||||
 | 
					mapping between such mark and hg revision hash.  Together they provide for a
 | 
				
			||||||
 | 
					(consistent) view of the synchronization state of things.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					When operating with shared-marks files, the `marks-git` and `marks-hg` files
 | 
				
			||||||
 | 
					are shared among all repos.  As such, they are then found in the `.git/hg`
 | 
				
			||||||
 | 
					directory (rather than a repo subdirectory).
 | 
				
			||||||
 | 
					As there is really only one hg repository
 | 
				
			||||||
 | 
					(the shared storage "union bag" in `.git/hg/.hg`), only 1 set of marks files
 | 
				
			||||||
 | 
					should track the mapping between commit hash and revision hash.
 | 
				
			||||||
 | 
					Each individual remote then only adds some metadata (e.g regarding heads).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Upon a fetch, the helper uses the `marks-hg` file to decide what is already present
 | 
				
			||||||
 | 
					and what not.  The required parts are then retrieved from Mercurial and turned
 | 
				
			||||||
 | 
					into a `git-fast-import` stream as expected by `import` capability of
 | 
				
			||||||
 | 
					https://www.kernel.org/pub/software/scm/git/docs/gitremote-helpers.html[gitremote-helpers(1)].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Upon a push, the helper has specified the `push` capability in the new approach, and
 | 
				
			||||||
 | 
					so git will provide a list of refspecs indicating what should go where.
 | 
				
			||||||
 | 
					If the refspecs indicates a remote delete, it is performed appropriately the Mercurial way.
 | 
				
			||||||
 | 
					If it is a regular push, then git-fast-export is invoked (using the existing `marks-git`)
 | 
				
			||||||
 | 
					and the stream is processed and turned into Mercurial commits (along with bookmarks, etc).
 | 
				
			||||||
 | 
					If the refspec specifies a `src:dest` rename, then the requested remote refname is tracked
 | 
				
			||||||
 | 
					accordingly.  If a dry-run is requested, no remote is touched and no (marks) state of
 | 
				
			||||||
 | 
					the run is retained.
 | 
				
			||||||
							
								
								
									
										1020
									
								
								git-hg-helper
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										1020
									
								
								git-hg-helper
									
									
									
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1451
									
								
								git-remote-hg
									
									
									
									
									
								
							
							
						
						
									
										1451
									
								
								git-remote-hg
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										45
									
								
								setup.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								setup.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
				
			|||||||
 | 
					# git-remote-hg setuptools script
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import setuptools
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# strip leading v
 | 
				
			||||||
 | 
					version = 'v1.0.3'[1:]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# check for released version
 | 
				
			||||||
 | 
					assert (len(version) > 0)
 | 
				
			||||||
 | 
					assert (version.find('-') < 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					long_description = \
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					'git-remote-hg' is a gitremote protocol helper for Mercurial.
 | 
				
			||||||
 | 
					It allows you to clone, fetch and push to and from Mercurial repositories as if
 | 
				
			||||||
 | 
					they were Git ones using a hg::some-url URL.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					See the homepage for much more explanation.
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CLASSIFIERS = [
 | 
				
			||||||
 | 
					    "Programming Language :: Python",
 | 
				
			||||||
 | 
					    "Programming Language :: Python :: 2",
 | 
				
			||||||
 | 
					    "Programming Language :: Python :: 2.7",
 | 
				
			||||||
 | 
					    "Programming Language :: Python :: 3",
 | 
				
			||||||
 | 
					    "Programming Language :: Python :: 3.6",
 | 
				
			||||||
 | 
					    "License :: OSI Approved",
 | 
				
			||||||
 | 
					    "License :: OSI Approved :: GNU General Public License v2 (GPLv2)",
 | 
				
			||||||
 | 
					    "Development Status :: 5 - Production/Stable",
 | 
				
			||||||
 | 
					    "Intended Audience :: Developers",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					setuptools.setup(name="git-remote-hg",
 | 
				
			||||||
 | 
					      version=version,
 | 
				
			||||||
 | 
					      author="Mark Nauwelaerts",
 | 
				
			||||||
 | 
					      author_email="mnauw@users.sourceforge.net",
 | 
				
			||||||
 | 
					      url="http://github.com/mnauw/git-remote-hg",
 | 
				
			||||||
 | 
					      description="access hg repositories as git remotes",
 | 
				
			||||||
 | 
					      long_description=long_description,
 | 
				
			||||||
 | 
					      license="GPLv2",
 | 
				
			||||||
 | 
					      keywords="git hg mercurial",
 | 
				
			||||||
 | 
					      scripts=["git-remote-hg", "git-hg-helper"],
 | 
				
			||||||
 | 
					      classifiers=CLASSIFIERS
 | 
				
			||||||
 | 
					     )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										775
									
								
								test-hg.sh
									
									
									
									
									
								
							
							
						
						
									
										775
									
								
								test-hg.sh
									
									
									
									
									
								
							@@ -1,775 +0,0 @@
 | 
				
			|||||||
#!/bin/sh
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# Copyright (c) 2012 Felipe Contreras
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# Base commands from hg-git tests:
 | 
					 | 
				
			||||||
# https://bitbucket.org/durin42/hg-git/src
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test_description='Test remote-hg'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test -n "$TEST_DIRECTORY" || TEST_DIRECTORY=${0%/*}/../../t
 | 
					 | 
				
			||||||
. "$TEST_DIRECTORY"/test-lib.sh
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if ! test_have_prereq PYTHON
 | 
					 | 
				
			||||||
then
 | 
					 | 
				
			||||||
	skip_all='skipping remote-hg tests; python not available'
 | 
					 | 
				
			||||||
	test_done
 | 
					 | 
				
			||||||
fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if ! python -c 'import mercurial'
 | 
					 | 
				
			||||||
then
 | 
					 | 
				
			||||||
	skip_all='skipping remote-hg tests; mercurial not available'
 | 
					 | 
				
			||||||
	test_done
 | 
					 | 
				
			||||||
fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
check () {
 | 
					 | 
				
			||||||
	echo $3 >expected &&
 | 
					 | 
				
			||||||
	git --git-dir=$1/.git log --format='%s' -1 $2 >actual
 | 
					 | 
				
			||||||
	test_cmp expected actual
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
check_branch () {
 | 
					 | 
				
			||||||
	if test -n "$3"
 | 
					 | 
				
			||||||
	then
 | 
					 | 
				
			||||||
		echo $3 >expected &&
 | 
					 | 
				
			||||||
		hg -R $1 log -r $2 --template '{desc}\n' >actual &&
 | 
					 | 
				
			||||||
		test_cmp expected actual
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		hg -R $1 branches >out &&
 | 
					 | 
				
			||||||
		! grep $2 out
 | 
					 | 
				
			||||||
	fi
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
check_bookmark () {
 | 
					 | 
				
			||||||
	if test -n "$3"
 | 
					 | 
				
			||||||
	then
 | 
					 | 
				
			||||||
		echo $3 >expected &&
 | 
					 | 
				
			||||||
		hg -R $1 log -r "bookmark('$2')" --template '{desc}\n' >actual &&
 | 
					 | 
				
			||||||
		test_cmp expected actual
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		hg -R $1 bookmarks >out &&
 | 
					 | 
				
			||||||
		! grep $2 out
 | 
					 | 
				
			||||||
	fi
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
check_push () {
 | 
					 | 
				
			||||||
	expected_ret=$1 ret=0 ref_ret=0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	shift
 | 
					 | 
				
			||||||
	git push origin "$@" 2>error
 | 
					 | 
				
			||||||
	ret=$?
 | 
					 | 
				
			||||||
	cat error
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	while IFS=':' read branch kind
 | 
					 | 
				
			||||||
	do
 | 
					 | 
				
			||||||
		case "$kind" in
 | 
					 | 
				
			||||||
		'new')
 | 
					 | 
				
			||||||
			grep "^ \* \[new branch\] *${branch} -> ${branch}$" error || ref_ret=1
 | 
					 | 
				
			||||||
			;;
 | 
					 | 
				
			||||||
		'non-fast-forward')
 | 
					 | 
				
			||||||
			grep "^ ! \[rejected\] *${branch} -> ${branch} (non-fast-forward)$" error || ref_ret=1
 | 
					 | 
				
			||||||
			;;
 | 
					 | 
				
			||||||
		'fetch-first')
 | 
					 | 
				
			||||||
			grep "^ ! \[rejected\] *${branch} -> ${branch} (fetch first)$" error || ref_ret=1
 | 
					 | 
				
			||||||
			;;
 | 
					 | 
				
			||||||
		'forced-update')
 | 
					 | 
				
			||||||
			grep "^ + [a-f0-9]*\.\.\.[a-f0-9]* *${branch} -> ${branch} (forced update)$" error || ref_ret=1
 | 
					 | 
				
			||||||
			;;
 | 
					 | 
				
			||||||
		'')
 | 
					 | 
				
			||||||
			grep "^   [a-f0-9]*\.\.[a-f0-9]* *${branch} -> ${branch}$" error || ref_ret=1
 | 
					 | 
				
			||||||
			;;
 | 
					 | 
				
			||||||
		esac
 | 
					 | 
				
			||||||
		test $ref_ret -ne 0 && echo "match for '$branch' failed" && break
 | 
					 | 
				
			||||||
	done
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if test $expected_ret -ne $ret || test $ref_ret -ne 0
 | 
					 | 
				
			||||||
	then
 | 
					 | 
				
			||||||
		return 1
 | 
					 | 
				
			||||||
	fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
setup () {
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	echo "[ui]"
 | 
					 | 
				
			||||||
	echo "username = H G Wells <wells@example.com>"
 | 
					 | 
				
			||||||
	echo "[extensions]"
 | 
					 | 
				
			||||||
	echo "mq ="
 | 
					 | 
				
			||||||
	) >>"$HOME"/.hgrc &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0230" &&
 | 
					 | 
				
			||||||
	GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE" &&
 | 
					 | 
				
			||||||
	export GIT_COMMITTER_DATE GIT_AUTHOR_DATE
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
setup
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test_expect_success 'cloning' '
 | 
					 | 
				
			||||||
	test_when_finished "rm -rf gitrepo*" &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	hg init hgrepo &&
 | 
					 | 
				
			||||||
	cd hgrepo &&
 | 
					 | 
				
			||||||
	echo zero >content &&
 | 
					 | 
				
			||||||
	hg add content &&
 | 
					 | 
				
			||||||
	hg commit -m zero
 | 
					 | 
				
			||||||
	) &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	git clone "hg::hgrepo" gitrepo &&
 | 
					 | 
				
			||||||
	check gitrepo HEAD zero
 | 
					 | 
				
			||||||
'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test_expect_success 'cloning with branches' '
 | 
					 | 
				
			||||||
	test_when_finished "rm -rf gitrepo*" &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	cd hgrepo &&
 | 
					 | 
				
			||||||
	hg branch next &&
 | 
					 | 
				
			||||||
	echo next >content &&
 | 
					 | 
				
			||||||
	hg commit -m next
 | 
					 | 
				
			||||||
	) &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	git clone "hg::hgrepo" gitrepo &&
 | 
					 | 
				
			||||||
	check gitrepo origin/branches/next next
 | 
					 | 
				
			||||||
'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test_expect_success 'cloning with bookmarks' '
 | 
					 | 
				
			||||||
	test_when_finished "rm -rf gitrepo*" &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	cd hgrepo &&
 | 
					 | 
				
			||||||
	hg checkout default &&
 | 
					 | 
				
			||||||
	hg bookmark feature-a &&
 | 
					 | 
				
			||||||
	echo feature-a >content &&
 | 
					 | 
				
			||||||
	hg commit -m feature-a
 | 
					 | 
				
			||||||
	) &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	git clone "hg::hgrepo" gitrepo &&
 | 
					 | 
				
			||||||
	check gitrepo origin/feature-a feature-a
 | 
					 | 
				
			||||||
'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test_expect_success 'update bookmark' '
 | 
					 | 
				
			||||||
	test_when_finished "rm -rf gitrepo*" &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	cd hgrepo &&
 | 
					 | 
				
			||||||
	hg bookmark devel
 | 
					 | 
				
			||||||
	) &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	git clone "hg::hgrepo" gitrepo &&
 | 
					 | 
				
			||||||
	cd gitrepo &&
 | 
					 | 
				
			||||||
	git checkout --quiet devel &&
 | 
					 | 
				
			||||||
	echo devel >content &&
 | 
					 | 
				
			||||||
	git commit -a -m devel &&
 | 
					 | 
				
			||||||
	git push --quiet
 | 
					 | 
				
			||||||
	) &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	check_bookmark hgrepo devel devel
 | 
					 | 
				
			||||||
'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test_expect_success 'new bookmark' '
 | 
					 | 
				
			||||||
	test_when_finished "rm -rf gitrepo*" &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	git clone "hg::hgrepo" gitrepo &&
 | 
					 | 
				
			||||||
	cd gitrepo &&
 | 
					 | 
				
			||||||
	git checkout --quiet -b feature-b &&
 | 
					 | 
				
			||||||
	echo feature-b >content &&
 | 
					 | 
				
			||||||
	git commit -a -m feature-b &&
 | 
					 | 
				
			||||||
	git push --quiet origin feature-b
 | 
					 | 
				
			||||||
	) &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	check_bookmark hgrepo feature-b feature-b
 | 
					 | 
				
			||||||
'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# cleanup previous stuff
 | 
					 | 
				
			||||||
rm -rf hgrepo
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
author_test () {
 | 
					 | 
				
			||||||
	echo $1 >>content &&
 | 
					 | 
				
			||||||
	hg commit -u "$2" -m "add $1" &&
 | 
					 | 
				
			||||||
	echo "$3" >>../expected
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test_expect_success 'authors' '
 | 
					 | 
				
			||||||
	test_when_finished "rm -rf hgrepo gitrepo" &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	hg init hgrepo &&
 | 
					 | 
				
			||||||
	cd hgrepo &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	touch content &&
 | 
					 | 
				
			||||||
	hg add content &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	>../expected &&
 | 
					 | 
				
			||||||
	author_test alpha "" "H G Wells <wells@example.com>" &&
 | 
					 | 
				
			||||||
	author_test beta "beta" "beta <unknown>" &&
 | 
					 | 
				
			||||||
	author_test gamma "gamma <test@example.com> (comment)" "gamma <test@example.com>" &&
 | 
					 | 
				
			||||||
	author_test delta "<delta@example.com>" "Unknown <delta@example.com>" &&
 | 
					 | 
				
			||||||
	author_test epsilon "epsilon<test@example.com>" "epsilon <test@example.com>" &&
 | 
					 | 
				
			||||||
	author_test zeta "zeta <test@example.com" "zeta <test@example.com>" &&
 | 
					 | 
				
			||||||
	author_test eta " eta " "eta <unknown>" &&
 | 
					 | 
				
			||||||
	author_test theta "theta < test@example.com >" "theta <test@example.com>" &&
 | 
					 | 
				
			||||||
	author_test iota "iota >test@example.com>" "iota <test@example.com>" &&
 | 
					 | 
				
			||||||
	author_test kappa "kappa < test <at> example <dot> com>" "kappa <unknown>" &&
 | 
					 | 
				
			||||||
	author_test lambda "lambda@example.com" "Unknown <lambda@example.com>" &&
 | 
					 | 
				
			||||||
	author_test mu "mu.mu@example.com" "Unknown <mu.mu@example.com>"
 | 
					 | 
				
			||||||
	) &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	git clone "hg::hgrepo" gitrepo &&
 | 
					 | 
				
			||||||
	git --git-dir=gitrepo/.git log --reverse --format="%an <%ae>" >actual &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	test_cmp expected actual
 | 
					 | 
				
			||||||
'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test_expect_success 'strip' '
 | 
					 | 
				
			||||||
	test_when_finished "rm -rf hgrepo gitrepo" &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	hg init hgrepo &&
 | 
					 | 
				
			||||||
	cd hgrepo &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	echo one >>content &&
 | 
					 | 
				
			||||||
	hg add content &&
 | 
					 | 
				
			||||||
	hg commit -m one &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	echo two >>content &&
 | 
					 | 
				
			||||||
	hg commit -m two
 | 
					 | 
				
			||||||
	) &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	git clone "hg::hgrepo" gitrepo &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	cd hgrepo &&
 | 
					 | 
				
			||||||
	hg strip 1 &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	echo three >>content &&
 | 
					 | 
				
			||||||
	hg commit -m three &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	echo four >>content &&
 | 
					 | 
				
			||||||
	hg commit -m four
 | 
					 | 
				
			||||||
	) &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	cd gitrepo &&
 | 
					 | 
				
			||||||
	git fetch &&
 | 
					 | 
				
			||||||
	git log --format="%s" origin/master >../actual
 | 
					 | 
				
			||||||
	) &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	hg -R hgrepo log --template "{desc}\n" >expected &&
 | 
					 | 
				
			||||||
	test_cmp actual expected
 | 
					 | 
				
			||||||
'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test_expect_success 'remote push with master bookmark' '
 | 
					 | 
				
			||||||
	test_when_finished "rm -rf hgrepo gitrepo*" &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	hg init hgrepo &&
 | 
					 | 
				
			||||||
	cd hgrepo &&
 | 
					 | 
				
			||||||
	echo zero >content &&
 | 
					 | 
				
			||||||
	hg add content &&
 | 
					 | 
				
			||||||
	hg commit -m zero &&
 | 
					 | 
				
			||||||
	hg bookmark master &&
 | 
					 | 
				
			||||||
	echo one >content &&
 | 
					 | 
				
			||||||
	hg commit -m one
 | 
					 | 
				
			||||||
	) &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	git clone "hg::hgrepo" gitrepo &&
 | 
					 | 
				
			||||||
	cd gitrepo &&
 | 
					 | 
				
			||||||
	echo two >content &&
 | 
					 | 
				
			||||||
	git commit -a -m two &&
 | 
					 | 
				
			||||||
	git push
 | 
					 | 
				
			||||||
	) &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	check_branch hgrepo default two
 | 
					 | 
				
			||||||
'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
cat >expected <<\EOF
 | 
					 | 
				
			||||||
changeset:   0:6e2126489d3d
 | 
					 | 
				
			||||||
tag:         tip
 | 
					 | 
				
			||||||
user:        A U Thor <author@example.com>
 | 
					 | 
				
			||||||
date:        Mon Jan 01 00:00:00 2007 +0230
 | 
					 | 
				
			||||||
summary:     one
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
EOF
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test_expect_success 'remote push from master branch' '
 | 
					 | 
				
			||||||
	test_when_finished "rm -rf hgrepo gitrepo*" &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	hg init hgrepo &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	git init gitrepo &&
 | 
					 | 
				
			||||||
	cd gitrepo &&
 | 
					 | 
				
			||||||
	git remote add origin "hg::../hgrepo" &&
 | 
					 | 
				
			||||||
	echo one >content &&
 | 
					 | 
				
			||||||
	git add content &&
 | 
					 | 
				
			||||||
	git commit -a -m one &&
 | 
					 | 
				
			||||||
	git push origin master
 | 
					 | 
				
			||||||
	) &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	hg -R hgrepo log >actual &&
 | 
					 | 
				
			||||||
	cat actual &&
 | 
					 | 
				
			||||||
	test_cmp expected actual &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	check_branch hgrepo default one
 | 
					 | 
				
			||||||
'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
GIT_REMOTE_HG_TEST_REMOTE=1
 | 
					 | 
				
			||||||
export GIT_REMOTE_HG_TEST_REMOTE
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test_expect_success 'remote cloning' '
 | 
					 | 
				
			||||||
	test_when_finished "rm -rf gitrepo*" &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	hg init hgrepo &&
 | 
					 | 
				
			||||||
	cd hgrepo &&
 | 
					 | 
				
			||||||
	echo zero >content &&
 | 
					 | 
				
			||||||
	hg add content &&
 | 
					 | 
				
			||||||
	hg commit -m zero
 | 
					 | 
				
			||||||
	) &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	git clone "hg::hgrepo" gitrepo &&
 | 
					 | 
				
			||||||
	check gitrepo HEAD zero
 | 
					 | 
				
			||||||
'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test_expect_success 'moving remote clone' '
 | 
					 | 
				
			||||||
	test_when_finished "rm -rf gitrepo*" &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	git clone "hg::hgrepo" gitrepo &&
 | 
					 | 
				
			||||||
	mv gitrepo gitrepo2 &&
 | 
					 | 
				
			||||||
	cd gitrepo2 &&
 | 
					 | 
				
			||||||
	git fetch
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test_expect_success 'remote update bookmark' '
 | 
					 | 
				
			||||||
	test_when_finished "rm -rf gitrepo*" &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	cd hgrepo &&
 | 
					 | 
				
			||||||
	hg bookmark devel
 | 
					 | 
				
			||||||
	) &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	git clone "hg::hgrepo" gitrepo &&
 | 
					 | 
				
			||||||
	cd gitrepo &&
 | 
					 | 
				
			||||||
	git checkout --quiet devel &&
 | 
					 | 
				
			||||||
	echo devel >content &&
 | 
					 | 
				
			||||||
	git commit -a -m devel &&
 | 
					 | 
				
			||||||
	git push --quiet
 | 
					 | 
				
			||||||
	) &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	check_bookmark hgrepo devel devel
 | 
					 | 
				
			||||||
'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test_expect_success 'remote new bookmark' '
 | 
					 | 
				
			||||||
	test_when_finished "rm -rf gitrepo*" &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	git clone "hg::hgrepo" gitrepo &&
 | 
					 | 
				
			||||||
	cd gitrepo &&
 | 
					 | 
				
			||||||
	git checkout --quiet -b feature-b &&
 | 
					 | 
				
			||||||
	echo feature-b >content &&
 | 
					 | 
				
			||||||
	git commit -a -m feature-b &&
 | 
					 | 
				
			||||||
	git push --quiet origin feature-b
 | 
					 | 
				
			||||||
	) &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	check_bookmark hgrepo feature-b feature-b
 | 
					 | 
				
			||||||
'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test_expect_success 'remote push diverged' '
 | 
					 | 
				
			||||||
	test_when_finished "rm -rf gitrepo*" &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	git clone "hg::hgrepo" gitrepo &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	cd hgrepo &&
 | 
					 | 
				
			||||||
	hg checkout default &&
 | 
					 | 
				
			||||||
	echo bump >content &&
 | 
					 | 
				
			||||||
	hg commit -m bump
 | 
					 | 
				
			||||||
	) &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	cd gitrepo &&
 | 
					 | 
				
			||||||
	echo diverge >content &&
 | 
					 | 
				
			||||||
	git commit -a -m diverged &&
 | 
					 | 
				
			||||||
	check_push 1 <<-\EOF
 | 
					 | 
				
			||||||
	master:non-fast-forward
 | 
					 | 
				
			||||||
	EOF
 | 
					 | 
				
			||||||
	) &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	check_branch hgrepo default bump
 | 
					 | 
				
			||||||
'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test_expect_success 'remote update bookmark diverge' '
 | 
					 | 
				
			||||||
	test_when_finished "rm -rf gitrepo*" &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	cd hgrepo &&
 | 
					 | 
				
			||||||
	hg checkout tip^ &&
 | 
					 | 
				
			||||||
	hg bookmark diverge
 | 
					 | 
				
			||||||
	) &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	git clone "hg::hgrepo" gitrepo &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	cd hgrepo &&
 | 
					 | 
				
			||||||
	echo "bump bookmark" >content &&
 | 
					 | 
				
			||||||
	hg commit -m "bump bookmark"
 | 
					 | 
				
			||||||
	) &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	cd gitrepo &&
 | 
					 | 
				
			||||||
	git checkout --quiet diverge &&
 | 
					 | 
				
			||||||
	echo diverge >content &&
 | 
					 | 
				
			||||||
	git commit -a -m diverge &&
 | 
					 | 
				
			||||||
	check_push 1 <<-\EOF
 | 
					 | 
				
			||||||
	diverge:fetch-first
 | 
					 | 
				
			||||||
	EOF
 | 
					 | 
				
			||||||
	) &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	check_bookmark hgrepo diverge "bump bookmark"
 | 
					 | 
				
			||||||
'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test_expect_success 'remote new bookmark multiple branch head' '
 | 
					 | 
				
			||||||
	test_when_finished "rm -rf gitrepo*" &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	git clone "hg::hgrepo" gitrepo &&
 | 
					 | 
				
			||||||
	cd gitrepo &&
 | 
					 | 
				
			||||||
	git checkout --quiet -b feature-c HEAD^ &&
 | 
					 | 
				
			||||||
	echo feature-c >content &&
 | 
					 | 
				
			||||||
	git commit -a -m feature-c &&
 | 
					 | 
				
			||||||
	git push --quiet origin feature-c
 | 
					 | 
				
			||||||
	) &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	check_bookmark hgrepo feature-c feature-c
 | 
					 | 
				
			||||||
'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# cleanup previous stuff
 | 
					 | 
				
			||||||
rm -rf hgrepo
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test_expect_success 'fetch special filenames' '
 | 
					 | 
				
			||||||
	test_when_finished "rm -rf hgrepo gitrepo && LC_ALL=C" &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	LC_ALL=en_US.UTF-8
 | 
					 | 
				
			||||||
	export LC_ALL
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	hg init hgrepo &&
 | 
					 | 
				
			||||||
	cd hgrepo &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	echo test >> "æ rø" &&
 | 
					 | 
				
			||||||
	hg add "æ rø" &&
 | 
					 | 
				
			||||||
	echo test >> "ø~?" &&
 | 
					 | 
				
			||||||
	hg add "ø~?" &&
 | 
					 | 
				
			||||||
	hg commit -m add-utf-8 &&
 | 
					 | 
				
			||||||
	echo test >> "æ rø" &&
 | 
					 | 
				
			||||||
	hg commit -m test-utf-8 &&
 | 
					 | 
				
			||||||
	hg rm "ø~?" &&
 | 
					 | 
				
			||||||
	hg mv "æ rø" "ø~?" &&
 | 
					 | 
				
			||||||
	hg commit -m hg-mv-utf-8
 | 
					 | 
				
			||||||
	) &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	git clone "hg::hgrepo" gitrepo &&
 | 
					 | 
				
			||||||
	cd gitrepo &&
 | 
					 | 
				
			||||||
	git -c core.quotepath=false ls-files > ../actual
 | 
					 | 
				
			||||||
	) &&
 | 
					 | 
				
			||||||
	echo "ø~?" > expected &&
 | 
					 | 
				
			||||||
	test_cmp expected actual
 | 
					 | 
				
			||||||
'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test_expect_success 'push special filenames' '
 | 
					 | 
				
			||||||
	test_when_finished "rm -rf hgrepo gitrepo && LC_ALL=C" &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	mkdir -p tmp && cd tmp &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	LC_ALL=en_US.UTF-8
 | 
					 | 
				
			||||||
	export LC_ALL
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	hg init hgrepo &&
 | 
					 | 
				
			||||||
	cd hgrepo &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	echo one >> content &&
 | 
					 | 
				
			||||||
	hg add content &&
 | 
					 | 
				
			||||||
	hg commit -m one
 | 
					 | 
				
			||||||
	) &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	git clone "hg::hgrepo" gitrepo &&
 | 
					 | 
				
			||||||
	cd gitrepo &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	echo test >> "æ rø" &&
 | 
					 | 
				
			||||||
	git add "æ rø" &&
 | 
					 | 
				
			||||||
	git commit -m utf-8 &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	git push
 | 
					 | 
				
			||||||
	) &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(cd hgrepo &&
 | 
					 | 
				
			||||||
	hg update &&
 | 
					 | 
				
			||||||
	hg manifest > ../actual
 | 
					 | 
				
			||||||
	) &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	printf "content\næ rø\n" > expected &&
 | 
					 | 
				
			||||||
	test_cmp expected actual
 | 
					 | 
				
			||||||
'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
setup_big_push () {
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	hg init hgrepo &&
 | 
					 | 
				
			||||||
	cd hgrepo &&
 | 
					 | 
				
			||||||
	echo zero >content &&
 | 
					 | 
				
			||||||
	hg add content &&
 | 
					 | 
				
			||||||
	hg commit -m zero &&
 | 
					 | 
				
			||||||
	hg bookmark bad_bmark1 &&
 | 
					 | 
				
			||||||
	echo one >content &&
 | 
					 | 
				
			||||||
	hg commit -m one &&
 | 
					 | 
				
			||||||
	hg bookmark bad_bmark2 &&
 | 
					 | 
				
			||||||
	hg bookmark good_bmark &&
 | 
					 | 
				
			||||||
	hg bookmark -i good_bmark &&
 | 
					 | 
				
			||||||
	hg -q branch good_branch &&
 | 
					 | 
				
			||||||
	echo "good branch" >content &&
 | 
					 | 
				
			||||||
	hg commit -m "good branch" &&
 | 
					 | 
				
			||||||
	hg -q branch bad_branch &&
 | 
					 | 
				
			||||||
	echo "bad branch" >content &&
 | 
					 | 
				
			||||||
	hg commit -m "bad branch"
 | 
					 | 
				
			||||||
	) &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	git clone "hg::hgrepo" gitrepo &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	cd gitrepo &&
 | 
					 | 
				
			||||||
	echo two >content &&
 | 
					 | 
				
			||||||
	git commit -q -a -m two &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	git checkout -q good_bmark &&
 | 
					 | 
				
			||||||
	echo three >content &&
 | 
					 | 
				
			||||||
	git commit -q -a -m three &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	git checkout -q bad_bmark1 &&
 | 
					 | 
				
			||||||
	git reset --hard HEAD^ &&
 | 
					 | 
				
			||||||
	echo four >content &&
 | 
					 | 
				
			||||||
	git commit -q -a -m four &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	git checkout -q bad_bmark2 &&
 | 
					 | 
				
			||||||
	git reset --hard HEAD^ &&
 | 
					 | 
				
			||||||
	echo five >content &&
 | 
					 | 
				
			||||||
	git commit -q -a -m five &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	git checkout -q -b new_bmark master &&
 | 
					 | 
				
			||||||
	echo six >content &&
 | 
					 | 
				
			||||||
	git commit -q -a -m six &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	git checkout -q branches/good_branch &&
 | 
					 | 
				
			||||||
	echo seven >content &&
 | 
					 | 
				
			||||||
	git commit -q -a -m seven &&
 | 
					 | 
				
			||||||
	echo eight >content &&
 | 
					 | 
				
			||||||
	git commit -q -a -m eight &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	git checkout -q branches/bad_branch &&
 | 
					 | 
				
			||||||
	git reset --hard HEAD^ &&
 | 
					 | 
				
			||||||
	echo nine >content &&
 | 
					 | 
				
			||||||
	git commit -q -a -m nine &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	git checkout -q -b branches/new_branch master &&
 | 
					 | 
				
			||||||
	echo ten >content &&
 | 
					 | 
				
			||||||
	git commit -q -a -m ten
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test_expect_success 'remote big push' '
 | 
					 | 
				
			||||||
	test_when_finished "rm -rf hgrepo gitrepo*" &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	setup_big_push
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	cd gitrepo &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	check_push 1 --all <<-\EOF
 | 
					 | 
				
			||||||
	master
 | 
					 | 
				
			||||||
	good_bmark
 | 
					 | 
				
			||||||
	branches/good_branch
 | 
					 | 
				
			||||||
	new_bmark:new
 | 
					 | 
				
			||||||
	branches/new_branch:new
 | 
					 | 
				
			||||||
	bad_bmark1:non-fast-forward
 | 
					 | 
				
			||||||
	bad_bmark2:non-fast-forward
 | 
					 | 
				
			||||||
	branches/bad_branch:non-fast-forward
 | 
					 | 
				
			||||||
	EOF
 | 
					 | 
				
			||||||
	) &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	check_branch hgrepo default one &&
 | 
					 | 
				
			||||||
	check_branch hgrepo good_branch "good branch" &&
 | 
					 | 
				
			||||||
	check_branch hgrepo bad_branch "bad branch" &&
 | 
					 | 
				
			||||||
	check_branch hgrepo new_branch '' &&
 | 
					 | 
				
			||||||
	check_bookmark hgrepo good_bmark one &&
 | 
					 | 
				
			||||||
	check_bookmark hgrepo bad_bmark1 one &&
 | 
					 | 
				
			||||||
	check_bookmark hgrepo bad_bmark2 one &&
 | 
					 | 
				
			||||||
	check_bookmark hgrepo new_bmark ''
 | 
					 | 
				
			||||||
'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test_expect_success 'remote big push fetch first' '
 | 
					 | 
				
			||||||
	test_when_finished "rm -rf hgrepo gitrepo*" &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	hg init hgrepo &&
 | 
					 | 
				
			||||||
	cd hgrepo &&
 | 
					 | 
				
			||||||
	echo zero >content &&
 | 
					 | 
				
			||||||
	hg add content &&
 | 
					 | 
				
			||||||
	hg commit -m zero &&
 | 
					 | 
				
			||||||
	hg bookmark bad_bmark &&
 | 
					 | 
				
			||||||
	hg bookmark good_bmark &&
 | 
					 | 
				
			||||||
	hg bookmark -i good_bmark &&
 | 
					 | 
				
			||||||
	hg -q branch good_branch &&
 | 
					 | 
				
			||||||
	echo "good branch" >content &&
 | 
					 | 
				
			||||||
	hg commit -m "good branch" &&
 | 
					 | 
				
			||||||
	hg -q branch bad_branch &&
 | 
					 | 
				
			||||||
	echo "bad branch" >content &&
 | 
					 | 
				
			||||||
	hg commit -m "bad branch"
 | 
					 | 
				
			||||||
	) &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	git clone "hg::hgrepo" gitrepo &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	cd hgrepo &&
 | 
					 | 
				
			||||||
	hg bookmark -f bad_bmark &&
 | 
					 | 
				
			||||||
	echo update_bmark >content &&
 | 
					 | 
				
			||||||
	hg commit -m "update bmark"
 | 
					 | 
				
			||||||
	) &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	cd gitrepo &&
 | 
					 | 
				
			||||||
	echo two >content &&
 | 
					 | 
				
			||||||
	git commit -q -a -m two &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	git checkout -q good_bmark &&
 | 
					 | 
				
			||||||
	echo three >content &&
 | 
					 | 
				
			||||||
	git commit -q -a -m three &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	git checkout -q bad_bmark &&
 | 
					 | 
				
			||||||
	echo four >content &&
 | 
					 | 
				
			||||||
	git commit -q -a -m four &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	git checkout -q branches/bad_branch &&
 | 
					 | 
				
			||||||
	echo five >content &&
 | 
					 | 
				
			||||||
	git commit -q -a -m five &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	check_push 1 --all <<-\EOF &&
 | 
					 | 
				
			||||||
	master
 | 
					 | 
				
			||||||
	good_bmark
 | 
					 | 
				
			||||||
	bad_bmark:fetch-first
 | 
					 | 
				
			||||||
	branches/bad_branch:festch-first
 | 
					 | 
				
			||||||
	EOF
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	git fetch &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	check_push 1 --all <<-\EOF
 | 
					 | 
				
			||||||
	master
 | 
					 | 
				
			||||||
	good_bmark
 | 
					 | 
				
			||||||
	bad_bmark:non-fast-forward
 | 
					 | 
				
			||||||
	branches/bad_branch:non-fast-forward
 | 
					 | 
				
			||||||
	EOF
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test_expect_failure 'remote big push force' '
 | 
					 | 
				
			||||||
	test_when_finished "rm -rf hgrepo gitrepo*" &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	setup_big_push
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	cd gitrepo &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	check_push 0 --force --all <<-\EOF
 | 
					 | 
				
			||||||
	master
 | 
					 | 
				
			||||||
	good_bmark
 | 
					 | 
				
			||||||
	branches/good_branch
 | 
					 | 
				
			||||||
	new_bmark:new
 | 
					 | 
				
			||||||
	branches/new_branch:new
 | 
					 | 
				
			||||||
	bad_bmark1:forced-update
 | 
					 | 
				
			||||||
	bad_bmark2:forced-update
 | 
					 | 
				
			||||||
	branches/bad_branch:forced-update
 | 
					 | 
				
			||||||
	EOF
 | 
					 | 
				
			||||||
	) &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	check_branch hgrepo default six &&
 | 
					 | 
				
			||||||
	check_branch hgrepo good_branch eight &&
 | 
					 | 
				
			||||||
	check_branch hgrepo bad_branch nine &&
 | 
					 | 
				
			||||||
	check_branch hgrepo new_branch ten &&
 | 
					 | 
				
			||||||
	check_bookmark hgrepo good_bmark three &&
 | 
					 | 
				
			||||||
	check_bookmark hgrepo bad_bmark1 four &&
 | 
					 | 
				
			||||||
	check_bookmark hgrepo bad_bmark2 five &&
 | 
					 | 
				
			||||||
	check_bookmark hgrepo new_bmark six
 | 
					 | 
				
			||||||
'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test_expect_failure 'remote big push dry-run' '
 | 
					 | 
				
			||||||
	test_when_finished "rm -rf hgrepo gitrepo*" &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	setup_big_push
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	cd gitrepo &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	check_push 1 --dry-run --all <<-\EOF &&
 | 
					 | 
				
			||||||
	master
 | 
					 | 
				
			||||||
	good_bmark
 | 
					 | 
				
			||||||
	branches/good_branch
 | 
					 | 
				
			||||||
	new_bmark:new
 | 
					 | 
				
			||||||
	branches/new_branch:new
 | 
					 | 
				
			||||||
	bad_bmark1:non-fast-forward
 | 
					 | 
				
			||||||
	bad_bmark2:non-fast-forward
 | 
					 | 
				
			||||||
	branches/bad_branch:non-fast-forward
 | 
					 | 
				
			||||||
	EOF
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	check_push 0 --dry-run master good_bmark new_bmark branches/good_branch branches/new_branch <<-\EOF
 | 
					 | 
				
			||||||
	master
 | 
					 | 
				
			||||||
	good_bmark
 | 
					 | 
				
			||||||
	branches/good_branch
 | 
					 | 
				
			||||||
	new_bmark:new
 | 
					 | 
				
			||||||
	branches/new_branch:new
 | 
					 | 
				
			||||||
	EOF
 | 
					 | 
				
			||||||
	) &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	check_branch hgrepo default one &&
 | 
					 | 
				
			||||||
	check_branch hgrepo good_branch "good branch" &&
 | 
					 | 
				
			||||||
	check_branch hgrepo bad_branch "bad branch" &&
 | 
					 | 
				
			||||||
	check_branch hgrepo new_branch '' &&
 | 
					 | 
				
			||||||
	check_bookmark hgrepo good_bmark one &&
 | 
					 | 
				
			||||||
	check_bookmark hgrepo bad_bmark1 one &&
 | 
					 | 
				
			||||||
	check_bookmark hgrepo bad_bmark2 one &&
 | 
					 | 
				
			||||||
	check_bookmark hgrepo new_bmark ''
 | 
					 | 
				
			||||||
'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test_expect_success 'remote double failed push' '
 | 
					 | 
				
			||||||
	test_when_finished "rm -rf hgrepo gitrepo*" &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	hg init hgrepo &&
 | 
					 | 
				
			||||||
	cd hgrepo &&
 | 
					 | 
				
			||||||
	echo zero >content &&
 | 
					 | 
				
			||||||
	hg add content &&
 | 
					 | 
				
			||||||
	hg commit -m zero &&
 | 
					 | 
				
			||||||
	echo one >content &&
 | 
					 | 
				
			||||||
	hg commit -m one
 | 
					 | 
				
			||||||
	) &&
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
	git clone "hg::hgrepo" gitrepo &&
 | 
					 | 
				
			||||||
	cd gitrepo &&
 | 
					 | 
				
			||||||
	git reset --hard HEAD^ &&
 | 
					 | 
				
			||||||
	echo two >content &&
 | 
					 | 
				
			||||||
	git commit -a -m two &&
 | 
					 | 
				
			||||||
	test_expect_code 1 git push &&
 | 
					 | 
				
			||||||
	test_expect_code 1 git push
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test_done
 | 
					 | 
				
			||||||
							
								
								
									
										3
									
								
								test/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								test/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					test-results/
 | 
				
			||||||
 | 
					trash directory.*/
 | 
				
			||||||
 | 
					.prove
 | 
				
			||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
RM ?= rm -f
 | 
					RM ?= rm -f
 | 
				
			||||||
 | 
					
 | 
				
			||||||
T = $(wildcard ../test-*.sh)
 | 
					T = main.t main-push.t bidi.t helper.t
 | 
				
			||||||
TEST_DIRECTORY := $(CURDIR)
 | 
					TEST_DIRECTORY := $(CURDIR)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export TEST_DIRECTORY
 | 
					export TEST_DIRECTORY
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,17 +8,12 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
test_description='Test bidirectionality of remote-hg'
 | 
					test_description='Test bidirectionality of remote-hg'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
. ./test-lib.sh
 | 
					test -n "$TEST_DIRECTORY" || TEST_DIRECTORY=$(dirname $0)/
 | 
				
			||||||
 | 
					. "$TEST_DIRECTORY"/test-lib.sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if ! test_have_prereq PYTHON
 | 
					if ! test_have_prereq PYTHON
 | 
				
			||||||
then
 | 
					then
 | 
				
			||||||
	skip_all='skipping remote-hg tests; python not available'
 | 
						skip_all='skipping remote-hg tests; python with mercurial not available'
 | 
				
			||||||
	test_done
 | 
					 | 
				
			||||||
fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if ! python -c 'import mercurial'
 | 
					 | 
				
			||||||
then
 | 
					 | 
				
			||||||
	skip_all='skipping remote-hg tests; mercurial not available'
 | 
					 | 
				
			||||||
	test_done
 | 
						test_done
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -45,26 +40,26 @@ hg_push () {
 | 
				
			|||||||
	git checkout -q -b tmp &&
 | 
						git checkout -q -b tmp &&
 | 
				
			||||||
	git fetch -q "hg::../$1" 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*' &&
 | 
						git fetch -q "hg::../$1" 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*' &&
 | 
				
			||||||
	git checkout -q @{-1} &&
 | 
						git checkout -q @{-1} &&
 | 
				
			||||||
	git branch -q -D tmp 2>/dev/null || true
 | 
						git branch -q -D tmp 2> /dev/null || true
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
hg_log () {
 | 
					hg_log () {
 | 
				
			||||||
	hg -R $1 log --graph --debug
 | 
						hg -R $1 log --debug
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
setup () {
 | 
					setup () {
 | 
				
			||||||
	(
 | 
						cat > "$HOME"/.hgrc <<-EOF &&
 | 
				
			||||||
	echo "[ui]"
 | 
						[ui]
 | 
				
			||||||
	echo "username = A U Thor <author@example.com>"
 | 
						username = A U Thor <author@example.com>
 | 
				
			||||||
	echo "[defaults]"
 | 
						[defaults]
 | 
				
			||||||
	echo "backout = -d \"0 0\""
 | 
						backout = -d "0 0"
 | 
				
			||||||
	echo "commit = -d \"0 0\""
 | 
						commit = -d "0 0"
 | 
				
			||||||
	echo "debugrawcommit = -d \"0 0\""
 | 
						debugrawcommit = -d "0 0"
 | 
				
			||||||
	echo "tag = -d \"0 0\""
 | 
						tag = -d "0 0"
 | 
				
			||||||
	echo "[extensions]"
 | 
						[extensions]"
 | 
				
			||||||
	echo "graphlog ="
 | 
						graphlog =
 | 
				
			||||||
	) >>"$HOME"/.hgrc &&
 | 
						EOF
 | 
				
			||||||
	git config --global remote-hg.hg-git-compat true
 | 
						git config --global remote-hg.hg-git-compat true
 | 
				
			||||||
	git config --global remote-hg.track-branches true
 | 
						git config --global remote-hg.track-branches true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -83,22 +78,22 @@ test_expect_success 'encoding' '
 | 
				
			|||||||
	git init -q gitrepo &&
 | 
						git init -q gitrepo &&
 | 
				
			||||||
	cd gitrepo &&
 | 
						cd gitrepo &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	echo alpha >alpha &&
 | 
						echo alpha > alpha &&
 | 
				
			||||||
	git add alpha &&
 | 
						git add alpha &&
 | 
				
			||||||
	git commit -m "add älphà" &&
 | 
						git commit -m "add älphà" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	GIT_AUTHOR_NAME="tést èncödîng" &&
 | 
						GIT_AUTHOR_NAME="tést èncödîng" &&
 | 
				
			||||||
	export GIT_AUTHOR_NAME &&
 | 
						export GIT_AUTHOR_NAME &&
 | 
				
			||||||
	echo beta >beta &&
 | 
						echo beta > beta &&
 | 
				
			||||||
	git add beta &&
 | 
						git add beta &&
 | 
				
			||||||
	git commit -m "add beta" &&
 | 
						git commit -m "add beta" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	echo gamma >gamma &&
 | 
						echo gamma > gamma &&
 | 
				
			||||||
	git add gamma &&
 | 
						git add gamma &&
 | 
				
			||||||
	git commit -m "add gämmâ" &&
 | 
						git commit -m "add gämmâ" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	: TODO git config i18n.commitencoding latin-1 &&
 | 
						: TODO git config i18n.commitencoding latin-1 &&
 | 
				
			||||||
	echo delta >delta &&
 | 
						echo delta > delta &&
 | 
				
			||||||
	git add delta &&
 | 
						git add delta &&
 | 
				
			||||||
	git commit -m "add déltà"
 | 
						git commit -m "add déltà"
 | 
				
			||||||
	) &&
 | 
						) &&
 | 
				
			||||||
@@ -107,8 +102,8 @@ test_expect_success 'encoding' '
 | 
				
			|||||||
	git_clone hgrepo gitrepo2 &&
 | 
						git_clone hgrepo gitrepo2 &&
 | 
				
			||||||
	hg_clone gitrepo2 hgrepo2 &&
 | 
						hg_clone gitrepo2 hgrepo2 &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	HGENCODING=utf-8 hg_log hgrepo >expected &&
 | 
						HGENCODING=utf-8 hg_log hgrepo > expected &&
 | 
				
			||||||
	HGENCODING=utf-8 hg_log hgrepo2 >actual &&
 | 
						HGENCODING=utf-8 hg_log hgrepo2 > actual &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	test_cmp expected actual
 | 
						test_cmp expected actual
 | 
				
			||||||
'
 | 
					'
 | 
				
			||||||
@@ -119,14 +114,14 @@ test_expect_success 'file removal' '
 | 
				
			|||||||
	(
 | 
						(
 | 
				
			||||||
	git init -q gitrepo &&
 | 
						git init -q gitrepo &&
 | 
				
			||||||
	cd gitrepo &&
 | 
						cd gitrepo &&
 | 
				
			||||||
	echo alpha >alpha &&
 | 
						echo alpha > alpha &&
 | 
				
			||||||
	git add alpha &&
 | 
						git add alpha &&
 | 
				
			||||||
	git commit -m "add alpha" &&
 | 
						git commit -m "add alpha" &&
 | 
				
			||||||
	echo beta >beta &&
 | 
						echo beta > beta &&
 | 
				
			||||||
	git add beta &&
 | 
						git add beta &&
 | 
				
			||||||
	git commit -m "add beta"
 | 
						git commit -m "add beta"
 | 
				
			||||||
	mkdir foo &&
 | 
						mkdir foo &&
 | 
				
			||||||
	echo blah >foo/bar &&
 | 
						echo blah > foo/bar &&
 | 
				
			||||||
	git add foo &&
 | 
						git add foo &&
 | 
				
			||||||
	git commit -m "add foo" &&
 | 
						git commit -m "add foo" &&
 | 
				
			||||||
	git rm alpha &&
 | 
						git rm alpha &&
 | 
				
			||||||
@@ -139,8 +134,8 @@ test_expect_success 'file removal' '
 | 
				
			|||||||
	git_clone hgrepo gitrepo2 &&
 | 
						git_clone hgrepo gitrepo2 &&
 | 
				
			||||||
	hg_clone gitrepo2 hgrepo2 &&
 | 
						hg_clone gitrepo2 hgrepo2 &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hg_log hgrepo >expected &&
 | 
						hg_log hgrepo > expected &&
 | 
				
			||||||
	hg_log hgrepo2 >actual &&
 | 
						hg_log hgrepo2 > actual &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	test_cmp expected actual
 | 
						test_cmp expected actual
 | 
				
			||||||
'
 | 
					'
 | 
				
			||||||
@@ -152,12 +147,12 @@ test_expect_success 'git tags' '
 | 
				
			|||||||
	git init -q gitrepo &&
 | 
						git init -q gitrepo &&
 | 
				
			||||||
	cd gitrepo &&
 | 
						cd gitrepo &&
 | 
				
			||||||
	git config receive.denyCurrentBranch ignore &&
 | 
						git config receive.denyCurrentBranch ignore &&
 | 
				
			||||||
	echo alpha >alpha &&
 | 
						echo alpha > alpha &&
 | 
				
			||||||
	git add alpha &&
 | 
						git add alpha &&
 | 
				
			||||||
	git commit -m "add alpha" &&
 | 
						git commit -m "add alpha" &&
 | 
				
			||||||
	git tag alpha &&
 | 
						git tag alpha &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	echo beta >beta &&
 | 
						echo beta > beta &&
 | 
				
			||||||
	git add beta &&
 | 
						git add beta &&
 | 
				
			||||||
	git commit -m "add beta" &&
 | 
						git commit -m "add beta" &&
 | 
				
			||||||
	git tag -a -m "added tag beta" beta
 | 
						git tag -a -m "added tag beta" beta
 | 
				
			||||||
@@ -167,8 +162,8 @@ test_expect_success 'git tags' '
 | 
				
			|||||||
	git_clone hgrepo gitrepo2 &&
 | 
						git_clone hgrepo gitrepo2 &&
 | 
				
			||||||
	hg_clone gitrepo2 hgrepo2 &&
 | 
						hg_clone gitrepo2 hgrepo2 &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hg_log hgrepo >expected &&
 | 
						hg_log hgrepo > expected &&
 | 
				
			||||||
	hg_log hgrepo2 >actual &&
 | 
						hg_log hgrepo2 > actual &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	test_cmp expected actual
 | 
						test_cmp expected actual
 | 
				
			||||||
'
 | 
					'
 | 
				
			||||||
@@ -180,7 +175,7 @@ test_expect_success 'hg branch' '
 | 
				
			|||||||
	git init -q gitrepo &&
 | 
						git init -q gitrepo &&
 | 
				
			||||||
	cd gitrepo &&
 | 
						cd gitrepo &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	echo alpha >alpha &&
 | 
						echo alpha > alpha &&
 | 
				
			||||||
	git add alpha &&
 | 
						git add alpha &&
 | 
				
			||||||
	git commit -q -m "add alpha" &&
 | 
						git commit -q -m "add alpha" &&
 | 
				
			||||||
	git checkout -q -b not-master
 | 
						git checkout -q -b not-master
 | 
				
			||||||
@@ -203,8 +198,9 @@ test_expect_success 'hg branch' '
 | 
				
			|||||||
	: Back to the common revision &&
 | 
						: Back to the common revision &&
 | 
				
			||||||
	(cd hgrepo && hg checkout default) &&
 | 
						(cd hgrepo && hg checkout default) &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hg_log hgrepo >expected &&
 | 
						# fetch does not affect phase, but pushing now does
 | 
				
			||||||
	hg_log hgrepo2 >actual &&
 | 
						hg_log hgrepo | grep -v phase > expected &&
 | 
				
			||||||
 | 
						hg_log hgrepo2 | grep -v phase > actual &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	test_cmp expected actual
 | 
						test_cmp expected actual
 | 
				
			||||||
'
 | 
					'
 | 
				
			||||||
@@ -216,7 +212,7 @@ test_expect_success 'hg tags' '
 | 
				
			|||||||
	git init -q gitrepo &&
 | 
						git init -q gitrepo &&
 | 
				
			||||||
	cd gitrepo &&
 | 
						cd gitrepo &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	echo alpha >alpha &&
 | 
						echo alpha > alpha &&
 | 
				
			||||||
	git add alpha &&
 | 
						git add alpha &&
 | 
				
			||||||
	git commit -m "add alpha" &&
 | 
						git commit -m "add alpha" &&
 | 
				
			||||||
	git checkout -q -b not-master
 | 
						git checkout -q -b not-master
 | 
				
			||||||
@@ -231,10 +227,50 @@ test_expect_success 'hg tags' '
 | 
				
			|||||||
	) &&
 | 
						) &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hg_push hgrepo gitrepo &&
 | 
						hg_push hgrepo gitrepo &&
 | 
				
			||||||
	hg_clone gitrepo hgrepo2 &&
 | 
						# pushing a fetched tag is a problem ...
 | 
				
			||||||
 | 
						{ hg_clone gitrepo hgrepo2 || true ; } &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hg_log hgrepo >expected &&
 | 
						# fetch does not affect phase, but pushing now does
 | 
				
			||||||
	hg_log hgrepo2 >actual &&
 | 
						hg_log hgrepo | grep -v phase > expected &&
 | 
				
			||||||
 | 
						hg_log hgrepo2 | grep -v phase > actual &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						test_cmp expected actual
 | 
				
			||||||
 | 
					'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_expect_success 'test timezones' '
 | 
				
			||||||
 | 
						test_when_finished "rm -rf gitrepo* hgrepo*" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						git init -q gitrepo &&
 | 
				
			||||||
 | 
						cd gitrepo &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						echo alpha > alpha &&
 | 
				
			||||||
 | 
						git add alpha &&
 | 
				
			||||||
 | 
						git commit -m "add alpha" --date="2007-01-01 00:00:00 +0000" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						echo beta > beta &&
 | 
				
			||||||
 | 
						git add beta &&
 | 
				
			||||||
 | 
						git commit -m "add beta" --date="2007-01-01 00:00:00 +0100" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						echo gamma > gamma &&
 | 
				
			||||||
 | 
						git add gamma &&
 | 
				
			||||||
 | 
						git commit -m "add gamma" --date="2007-01-01 00:00:00 -0100" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						echo delta > delta &&
 | 
				
			||||||
 | 
						git add delta &&
 | 
				
			||||||
 | 
						git commit -m "add delta" --date="2007-01-01 00:00:00 +0130" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						echo epsilon > epsilon &&
 | 
				
			||||||
 | 
						git add epsilon &&
 | 
				
			||||||
 | 
						git commit -m "add epsilon" --date="2007-01-01 00:00:00 -0130"
 | 
				
			||||||
 | 
						) &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hg_clone gitrepo hgrepo &&
 | 
				
			||||||
 | 
						git_clone hgrepo gitrepo2 &&
 | 
				
			||||||
 | 
						hg_clone gitrepo2 hgrepo2 &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hg_log hgrepo > expected &&
 | 
				
			||||||
 | 
						hg_log hgrepo2 > actual &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	test_cmp expected actual
 | 
						test_cmp expected actual
 | 
				
			||||||
'
 | 
					'
 | 
				
			||||||
							
								
								
									
										541
									
								
								test/helper.t
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										541
									
								
								test/helper.t
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,541 @@
 | 
				
			|||||||
 | 
					#!/bin/sh
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Copyright (c) 2016 Mark Nauwelaerts
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Base commands from hg-git tests:
 | 
				
			||||||
 | 
					# https://bitbucket.org/durin42/hg-git/src
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_description='Test git-hg-helper'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test -n "$TEST_DIRECTORY" || TEST_DIRECTORY=$(dirname $0)/
 | 
				
			||||||
 | 
					. "$TEST_DIRECTORY"/test-lib.sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if ! test_have_prereq PYTHON
 | 
				
			||||||
 | 
					then
 | 
				
			||||||
 | 
						skip_all='skipping remote-hg tests; python with mercurial not available'
 | 
				
			||||||
 | 
						test_done
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					setup () {
 | 
				
			||||||
 | 
						cat > "$HOME"/.hgrc <<-EOF &&
 | 
				
			||||||
 | 
						[ui]
 | 
				
			||||||
 | 
						username = H G Wells <wells@example.com>
 | 
				
			||||||
 | 
						[extensions]
 | 
				
			||||||
 | 
						mq =
 | 
				
			||||||
 | 
						strip =
 | 
				
			||||||
 | 
						[subrepos]
 | 
				
			||||||
 | 
						git:allowed = true
 | 
				
			||||||
 | 
						EOF
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0230" &&
 | 
				
			||||||
 | 
						GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE" &&
 | 
				
			||||||
 | 
						export GIT_COMMITTER_DATE GIT_AUTHOR_DATE
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					setup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					setup_repos () {
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						hg init hgrepo &&
 | 
				
			||||||
 | 
						cd hgrepo &&
 | 
				
			||||||
 | 
						echo zero > content &&
 | 
				
			||||||
 | 
						hg add content &&
 | 
				
			||||||
 | 
						hg commit -m zero
 | 
				
			||||||
 | 
						) &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						git clone hg::hgrepo gitrepo
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_expect_success 'subcommand help' '
 | 
				
			||||||
 | 
						test_when_finished "rm -rf gitrepo* hgrepo*" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setup_repos &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						cd gitrepo &&
 | 
				
			||||||
 | 
						test_expect_code 2 git-hg-helper help 2> ../help
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
						# remotes should be in help output
 | 
				
			||||||
 | 
						grep origin help
 | 
				
			||||||
 | 
					'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					git config --global remote-hg.shared-marks false
 | 
				
			||||||
 | 
					test_expect_success 'subcommand repo - no local proxy' '
 | 
				
			||||||
 | 
						test_when_finished "rm -rf gitrepo* hgrepo*" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setup_repos &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						cd hgrepo &&
 | 
				
			||||||
 | 
						pwd >../expected
 | 
				
			||||||
 | 
						) &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						cd gitrepo &&
 | 
				
			||||||
 | 
						git-hg-helper repo origin > ../actual
 | 
				
			||||||
 | 
						) &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						test_cmp expected actual
 | 
				
			||||||
 | 
					'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					git config --global --unset remote-hg.shared-marks
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GIT_REMOTE_HG_TEST_REMOTE=1 &&
 | 
				
			||||||
 | 
					export GIT_REMOTE_HG_TEST_REMOTE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_expect_success 'subcommand repo - with local proxy' '
 | 
				
			||||||
 | 
						test_when_finished "rm -rf gitrepo* hgrepo*" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setup_repos &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						cd gitrepo &&
 | 
				
			||||||
 | 
						export gitdir=`git rev-parse --git-dir`
 | 
				
			||||||
 | 
						# trick to normalize path
 | 
				
			||||||
 | 
						( cd $gitdir/hg/origin/clone && pwd ) >../expected &&
 | 
				
			||||||
 | 
						( cd `git-hg-helper repo origin` && pwd ) > ../actual
 | 
				
			||||||
 | 
						) &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						test_cmp expected actual
 | 
				
			||||||
 | 
					'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_expect_success 'subcommands hg-rev and git-rev' '
 | 
				
			||||||
 | 
						test_when_finished "rm -rf gitrepo* hgrepo*" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setup_repos &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						cd gitrepo &&
 | 
				
			||||||
 | 
						git rev-parse HEAD > rev-HEAD &&
 | 
				
			||||||
 | 
						test -s rev-HEAD &&
 | 
				
			||||||
 | 
						git-hg-helper hg-rev `cat rev-HEAD` > hg-HEAD &&
 | 
				
			||||||
 | 
						git-hg-helper git-rev `cat hg-HEAD` > git-HEAD &&
 | 
				
			||||||
 | 
						test_cmp rev-HEAD git-HEAD
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_expect_success 'subcommand gc' '
 | 
				
			||||||
 | 
						test_when_finished "rm -rf gitrepo* hgrepo*" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						hg init hgrepo &&
 | 
				
			||||||
 | 
						cd hgrepo &&
 | 
				
			||||||
 | 
						echo zero > content &&
 | 
				
			||||||
 | 
						hg add content &&
 | 
				
			||||||
 | 
						hg commit -m zero
 | 
				
			||||||
 | 
						echo one > content &&
 | 
				
			||||||
 | 
						hg commit -m one &&
 | 
				
			||||||
 | 
						echo two > content &&
 | 
				
			||||||
 | 
						hg commit -m two &&
 | 
				
			||||||
 | 
						echo three > content &&
 | 
				
			||||||
 | 
						hg commit -m three
 | 
				
			||||||
 | 
						) &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						git clone hg::hgrepo gitrepo &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						cd hgrepo &&
 | 
				
			||||||
 | 
						hg strip -r 1 &&
 | 
				
			||||||
 | 
						echo four > content &&
 | 
				
			||||||
 | 
						hg commit -m four
 | 
				
			||||||
 | 
						) &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						cd gitrepo &&
 | 
				
			||||||
 | 
						git fetch origin &&
 | 
				
			||||||
 | 
						git reset --hard origin/master &&
 | 
				
			||||||
 | 
						git gc &&
 | 
				
			||||||
 | 
						git-hg-helper gc --check-hg origin > output &&
 | 
				
			||||||
 | 
						cat output &&
 | 
				
			||||||
 | 
						grep "hg marks" output &&
 | 
				
			||||||
 | 
						grep "git marks" output
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_expect_success 'subcommand [some-repo]' '
 | 
				
			||||||
 | 
						test_when_finished "rm -rf gitrepo* hgrepo*" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setup_repos &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						cd hgrepo &&
 | 
				
			||||||
 | 
						echo one > content &&
 | 
				
			||||||
 | 
						hg commit -m one
 | 
				
			||||||
 | 
						) &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						cd gitrepo &&
 | 
				
			||||||
 | 
						git fetch origin
 | 
				
			||||||
 | 
						) &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hg log -R hgrepo > expected &&
 | 
				
			||||||
 | 
						# not inside gitrepo; test shared path handling
 | 
				
			||||||
 | 
						GIT_DIR=gitrepo/.git git-hg-helper origin log > actual
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						test_cmp expected actual
 | 
				
			||||||
 | 
					'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					setup_repo () {
 | 
				
			||||||
 | 
					    kind=$1 &&
 | 
				
			||||||
 | 
					    repo=$2 &&
 | 
				
			||||||
 | 
					    $kind init $repo &&
 | 
				
			||||||
 | 
					    (
 | 
				
			||||||
 | 
					    cd $repo &&
 | 
				
			||||||
 | 
					    echo zero > content_$repo &&
 | 
				
			||||||
 | 
					    $kind add content_$repo &&
 | 
				
			||||||
 | 
					    $kind commit -m zero_$repo
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					check () {
 | 
				
			||||||
 | 
						echo $3 > expected &&
 | 
				
			||||||
 | 
						git --git-dir=$1/.git log --format='%s' -1 $2 > actual &&
 | 
				
			||||||
 | 
						test_cmp expected actual
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					check_branch () {
 | 
				
			||||||
 | 
						if test -n "$3"
 | 
				
			||||||
 | 
						then
 | 
				
			||||||
 | 
							echo $3 > expected &&
 | 
				
			||||||
 | 
							hg -R $1 log -r $2 --template '{desc}\n' > actual &&
 | 
				
			||||||
 | 
							test_cmp expected actual
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							hg -R $1 branches > out &&
 | 
				
			||||||
 | 
							! grep $2 out
 | 
				
			||||||
 | 
						fi
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_expect_success 'subcommand sub initial update (hg and git subrepos)' '
 | 
				
			||||||
 | 
						test_when_finished "rm -rf gitrepo* hgrepo*" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setup_repo hg hgrepo &&
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						cd hgrepo &&
 | 
				
			||||||
 | 
						setup_repo hg sub_hg_a &&
 | 
				
			||||||
 | 
						setup_repo hg sub_hg_b &&
 | 
				
			||||||
 | 
						setup_repo git sub_git &&
 | 
				
			||||||
 | 
						echo "sub_hg_a = sub_hg_a" > .hgsub &&
 | 
				
			||||||
 | 
						echo "sub_hg_b = sub_hg_b" >> .hgsub &&
 | 
				
			||||||
 | 
						echo "sub_git = [git]sub_git" >> .hgsub &&
 | 
				
			||||||
 | 
						hg add .hgsub &&
 | 
				
			||||||
 | 
						hg commit -m substate
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						git clone hg::hgrepo gitrepo &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						cd gitrepo &&
 | 
				
			||||||
 | 
						git-hg-helper sub update --force &&
 | 
				
			||||||
 | 
						test -f content_hgrepo &&
 | 
				
			||||||
 | 
						test -f sub_hg_a/content_sub_hg_a &&
 | 
				
			||||||
 | 
						test -f sub_hg_b/content_sub_hg_b &&
 | 
				
			||||||
 | 
						test -f sub_git/content_sub_git
 | 
				
			||||||
 | 
						) &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						check gitrepo HEAD substate &&
 | 
				
			||||||
 | 
						check gitrepo/sub_hg_a HEAD zero_sub_hg_a &&
 | 
				
			||||||
 | 
						check gitrepo/sub_hg_b HEAD zero_sub_hg_b &&
 | 
				
			||||||
 | 
						check gitrepo/sub_git HEAD zero_sub_git
 | 
				
			||||||
 | 
					'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					setup_subrepos () {
 | 
				
			||||||
 | 
						setup_repo hg hgrepo &&
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						cd hgrepo &&
 | 
				
			||||||
 | 
						setup_repo hg sub_hg_a &&
 | 
				
			||||||
 | 
							(
 | 
				
			||||||
 | 
							cd sub_hg_a &&
 | 
				
			||||||
 | 
							setup_repo hg sub_hg_a_x &&
 | 
				
			||||||
 | 
							echo "sub_hg_a_x = sub_hg_a_x" > .hgsub &&
 | 
				
			||||||
 | 
							hg add .hgsub &&
 | 
				
			||||||
 | 
							hg commit -m substate_hg_a
 | 
				
			||||||
 | 
							) &&
 | 
				
			||||||
 | 
						setup_repo hg sub_hg_b &&
 | 
				
			||||||
 | 
							(
 | 
				
			||||||
 | 
							cd sub_hg_b &&
 | 
				
			||||||
 | 
							setup_repo git sub_git &&
 | 
				
			||||||
 | 
							echo "sub_git = [git]sub_git" > .hgsub &&
 | 
				
			||||||
 | 
							hg add .hgsub &&
 | 
				
			||||||
 | 
							hg commit -m substate_hg_b
 | 
				
			||||||
 | 
							) &&
 | 
				
			||||||
 | 
						echo "sub_hg_a = sub_hg_a" > .hgsub &&
 | 
				
			||||||
 | 
						echo "sub_hg_b = sub_hg_b" >> .hgsub &&
 | 
				
			||||||
 | 
						hg add .hgsub &&
 | 
				
			||||||
 | 
						hg commit -m substate
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_expect_success 'subcommand sub initial recursive update' '
 | 
				
			||||||
 | 
						test_when_finished "rm -rf gitrepo* hgrepo*" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setup_subrepos &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						git clone hg::hgrepo gitrepo &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						cd gitrepo &&
 | 
				
			||||||
 | 
						git-hg-helper sub --recursive update --force &&
 | 
				
			||||||
 | 
						test -f content_hgrepo &&
 | 
				
			||||||
 | 
						test -f sub_hg_a/content_sub_hg_a &&
 | 
				
			||||||
 | 
						test -f sub_hg_a/sub_hg_a_x/content_sub_hg_a_x &&
 | 
				
			||||||
 | 
						test -f sub_hg_b/content_sub_hg_b &&
 | 
				
			||||||
 | 
						test -f sub_hg_b/sub_git/content_sub_git
 | 
				
			||||||
 | 
						) &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						check gitrepo HEAD substate &&
 | 
				
			||||||
 | 
						check gitrepo/sub_hg_a HEAD substate_hg_a &&
 | 
				
			||||||
 | 
						check gitrepo/sub_hg_b HEAD substate_hg_b &&
 | 
				
			||||||
 | 
						check gitrepo/sub_hg_a/sub_hg_a_x HEAD zero_sub_hg_a_x &&
 | 
				
			||||||
 | 
						check gitrepo/sub_hg_b/sub_git HEAD zero_sub_git
 | 
				
			||||||
 | 
					'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_sub_update () {
 | 
				
			||||||
 | 
						export option=$1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setup_subrepos &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						git clone hg::hgrepo gitrepo &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						cd gitrepo &&
 | 
				
			||||||
 | 
						git-hg-helper sub --recursive update --force
 | 
				
			||||||
 | 
						) &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						cd hgrepo &&
 | 
				
			||||||
 | 
							(
 | 
				
			||||||
 | 
							 cd sub_hg_a &&
 | 
				
			||||||
 | 
								(
 | 
				
			||||||
 | 
								cd sub_hg_a_x &&
 | 
				
			||||||
 | 
								echo one > content_sub_hg_a_x &&
 | 
				
			||||||
 | 
								hg commit -m one_sub_hg_a_x
 | 
				
			||||||
 | 
								) &&
 | 
				
			||||||
 | 
							hg commit -m substate_updated_hg_a
 | 
				
			||||||
 | 
							) &&
 | 
				
			||||||
 | 
						hg commit -m substate_updated
 | 
				
			||||||
 | 
						) &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						cd gitrepo &&
 | 
				
			||||||
 | 
						git fetch origin &&
 | 
				
			||||||
 | 
						git merge origin/master &&
 | 
				
			||||||
 | 
						git-hg-helper sub --recursive update --force $option &&
 | 
				
			||||||
 | 
						test -f content_hgrepo &&
 | 
				
			||||||
 | 
						test -f sub_hg_a/content_sub_hg_a &&
 | 
				
			||||||
 | 
						test -f sub_hg_a/sub_hg_a_x/content_sub_hg_a_x &&
 | 
				
			||||||
 | 
						test -f sub_hg_b/content_sub_hg_b &&
 | 
				
			||||||
 | 
						test -f sub_hg_b/sub_git/content_sub_git
 | 
				
			||||||
 | 
						) &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						check gitrepo HEAD substate_updated &&
 | 
				
			||||||
 | 
						check gitrepo/sub_hg_a HEAD substate_updated_hg_a &&
 | 
				
			||||||
 | 
						check gitrepo/sub_hg_b HEAD substate_hg_b &&
 | 
				
			||||||
 | 
						check gitrepo/sub_hg_a/sub_hg_a_x HEAD one_sub_hg_a_x &&
 | 
				
			||||||
 | 
						check gitrepo/sub_hg_b/sub_git HEAD zero_sub_git
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_expect_success 'subcommand sub subsequent recursive update' '
 | 
				
			||||||
 | 
						test_when_finished "rm -rf gitrepo* hgrepo*" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						test_sub_update
 | 
				
			||||||
 | 
					'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_expect_success 'subcommand sub subsequent recursive update -- rebase' '
 | 
				
			||||||
 | 
						test_when_finished "rm -rf gitrepo* hgrepo*" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						test_sub_update --rebase
 | 
				
			||||||
 | 
					'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_expect_success 'subcommand sub subsequent recursive update -- merge' '
 | 
				
			||||||
 | 
						test_when_finished "rm -rf gitrepo* hgrepo*" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						test_sub_update --merge
 | 
				
			||||||
 | 
					'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					check_foreach_vars () {
 | 
				
			||||||
 | 
						cat $1 | while read kind sha1 rev path remainder
 | 
				
			||||||
 | 
						do
 | 
				
			||||||
 | 
						    ok=0
 | 
				
			||||||
 | 
						    if test "$kind" = "hg" ; then
 | 
				
			||||||
 | 
								if test "$sha1" != "$rev" ; then
 | 
				
			||||||
 | 
									ok=1
 | 
				
			||||||
 | 
								fi
 | 
				
			||||||
 | 
						    else
 | 
				
			||||||
 | 
								if test "$sha1" = "$rev" ; then
 | 
				
			||||||
 | 
									ok=1
 | 
				
			||||||
 | 
								fi
 | 
				
			||||||
 | 
						    fi
 | 
				
			||||||
 | 
						    test $ok -eq 1 || echo "invalid $kind $sha1 $rev $path"
 | 
				
			||||||
 | 
						    test $ok -eq 1 || return 1
 | 
				
			||||||
 | 
						done &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_sub_foreach () {
 | 
				
			||||||
 | 
						setup_subrepos &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						git clone hg::hgrepo gitrepo &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						cd gitrepo &&
 | 
				
			||||||
 | 
						git-hg-helper sub --recursive update --force &&
 | 
				
			||||||
 | 
						git-hg-helper sub --recursive --quiet foreach 'echo $kind $sha1 $rev $path $toplevel' > output &&
 | 
				
			||||||
 | 
						cat output &&
 | 
				
			||||||
 | 
						echo 1 > expected_git &&
 | 
				
			||||||
 | 
						grep -c ^git output > actual_git &&
 | 
				
			||||||
 | 
						test_cmp expected_git actual_git &&
 | 
				
			||||||
 | 
						echo 3 > expected_hg &&
 | 
				
			||||||
 | 
						grep -c ^hg output > actual_hg &&
 | 
				
			||||||
 | 
						test_cmp expected_hg actual_hg &&
 | 
				
			||||||
 | 
						grep '\(hg\|git\) [0-9a-f]* [0-9a-f]* sub[^ ]* /.*' output > actual &&
 | 
				
			||||||
 | 
						test_cmp output actual &&
 | 
				
			||||||
 | 
						check_foreach_vars output
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_expect_success 'subcommand sub foreach' '
 | 
				
			||||||
 | 
						test_when_finished "rm -rf gitrepo* hgrepo*" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						test_sub_foreach
 | 
				
			||||||
 | 
					'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_expect_success 'subcommand sub sync' '
 | 
				
			||||||
 | 
						test_when_finished "rm -rf gitrepo* hgrepo*" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setup_repo hg hgrepo &&
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						cd hgrepo &&
 | 
				
			||||||
 | 
						setup_repo hg sub_hg &&
 | 
				
			||||||
 | 
						echo "sub_hg = sub_hg" > .hgsub &&
 | 
				
			||||||
 | 
						hg add .hgsub &&
 | 
				
			||||||
 | 
						hg commit -m substate
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						git clone hg::hgrepo gitrepo &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						cd gitrepo &&
 | 
				
			||||||
 | 
						git-hg-helper sub update --force &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							(
 | 
				
			||||||
 | 
							cd sub_hg &&
 | 
				
			||||||
 | 
							grep url .git/config > ../expected &&
 | 
				
			||||||
 | 
							git config remote.origin.url foobar &&
 | 
				
			||||||
 | 
							grep foobar .git/config
 | 
				
			||||||
 | 
							) &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						git-hg-helper sub sync &&
 | 
				
			||||||
 | 
						grep url sub_hg/.git/config > actual &&
 | 
				
			||||||
 | 
						test_cmp expected actual
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_expect_success 'subcommand sub addstate' '
 | 
				
			||||||
 | 
						test_when_finished "rm -rf gitrepo* hgrepo*" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setup_repo hg hgrepo &&
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						cd hgrepo &&
 | 
				
			||||||
 | 
						setup_repo hg sub_hg &&
 | 
				
			||||||
 | 
						setup_repo git sub_git &&
 | 
				
			||||||
 | 
						echo "sub_hg = sub_hg" > .hgsub &&
 | 
				
			||||||
 | 
						echo "sub_git = [git]sub_git" >> .hgsub &&
 | 
				
			||||||
 | 
						hg add .hgsub &&
 | 
				
			||||||
 | 
						hg commit -m substate
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						git clone hg::hgrepo gitrepo &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						cd gitrepo &&
 | 
				
			||||||
 | 
						git-hg-helper sub update --force &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							(
 | 
				
			||||||
 | 
							cd sub_hg &&
 | 
				
			||||||
 | 
							echo one > content_sub_hg &&
 | 
				
			||||||
 | 
							git add content_sub_hg &&
 | 
				
			||||||
 | 
							git commit -m one_sub_hg &&
 | 
				
			||||||
 | 
							# detached HEAD
 | 
				
			||||||
 | 
							git push origin HEAD:master &&
 | 
				
			||||||
 | 
							# also fetch to ensure notes are updated
 | 
				
			||||||
 | 
							git fetch origin
 | 
				
			||||||
 | 
							) &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							(
 | 
				
			||||||
 | 
							cd sub_git &&
 | 
				
			||||||
 | 
							echo one > content_sub_git &&
 | 
				
			||||||
 | 
							git add content_sub_git &&
 | 
				
			||||||
 | 
							git commit -m one_sub_git &&
 | 
				
			||||||
 | 
							# detached HEAD; push revision to other side ... anywhere
 | 
				
			||||||
 | 
							git push origin HEAD:refs/heads/new
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
						) &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						cd gitrepo &&
 | 
				
			||||||
 | 
						git-hg-helper sub upstate &&
 | 
				
			||||||
 | 
						git diff &&
 | 
				
			||||||
 | 
						git status --porcelain | grep .hgsubstate &&
 | 
				
			||||||
 | 
						git add .hgsubstate &&
 | 
				
			||||||
 | 
						git commit -m update_sub &&
 | 
				
			||||||
 | 
						git push origin master
 | 
				
			||||||
 | 
						) &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hg clone hgrepo hgclone &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						cd hgclone &&
 | 
				
			||||||
 | 
						hg update
 | 
				
			||||||
 | 
						) &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						check_branch hgclone default update_sub &&
 | 
				
			||||||
 | 
						check_branch hgclone/sub_hg default one_sub_hg &&
 | 
				
			||||||
 | 
						check hgclone/sub_git HEAD one_sub_git
 | 
				
			||||||
 | 
					'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_expect_success 'subcommand sub status' '
 | 
				
			||||||
 | 
						test_when_finished "rm -rf gitrepo* hgrepo*" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setup_repo hg hgrepo &&
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						cd hgrepo &&
 | 
				
			||||||
 | 
						setup_repo hg sub_hg_a &&
 | 
				
			||||||
 | 
						setup_repo hg sub_hg_b &&
 | 
				
			||||||
 | 
						setup_repo git sub_git &&
 | 
				
			||||||
 | 
						echo "sub_hg_a = sub_hg_a" > .hgsub &&
 | 
				
			||||||
 | 
						echo "sub_hg_b = sub_hg_b" >> .hgsub &&
 | 
				
			||||||
 | 
						echo "sub_git = [git]sub_git" >> .hgsub &&
 | 
				
			||||||
 | 
						hg add .hgsub &&
 | 
				
			||||||
 | 
						hg commit -m substate
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						git clone hg::hgrepo gitrepo &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						cd gitrepo &&
 | 
				
			||||||
 | 
						git-hg-helper sub update --force sub_hg_a  &&
 | 
				
			||||||
 | 
						git-hg-helper sub update --force sub_git &&
 | 
				
			||||||
 | 
							(
 | 
				
			||||||
 | 
							# advance and add a tag to the git repo
 | 
				
			||||||
 | 
							cd sub_git &&
 | 
				
			||||||
 | 
							echo one > content_sub_git &&
 | 
				
			||||||
 | 
							git add content_sub_git &&
 | 
				
			||||||
 | 
							git commit -m one_sub_git &&
 | 
				
			||||||
 | 
							git tag feature-a
 | 
				
			||||||
 | 
							) &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						git-hg-helper sub status --cached > output &&
 | 
				
			||||||
 | 
						cat output &&
 | 
				
			||||||
 | 
						grep "^ .*sub_hg_a (.*master.*)$" output &&
 | 
				
			||||||
 | 
						grep "^-.*sub_hg_b$" output &&
 | 
				
			||||||
 | 
						grep "^+.*sub_git (feature-a~1)$" output &&
 | 
				
			||||||
 | 
						git-hg-helper sub status sub_git > output &&
 | 
				
			||||||
 | 
						cat output &&
 | 
				
			||||||
 | 
						grep "^+.*sub_git (feature-a)$" output > actual &&
 | 
				
			||||||
 | 
						test_cmp output actual
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_done
 | 
				
			||||||
@@ -8,22 +8,22 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
test_description='Test remote-hg output compared to hg-git'
 | 
					test_description='Test remote-hg output compared to hg-git'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
. ./test-lib.sh
 | 
					test -n "$TEST_DIRECTORY" || TEST_DIRECTORY=$(dirname $0)/
 | 
				
			||||||
 | 
					. "$TEST_DIRECTORY"/test-lib.sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if ! test_have_prereq PYTHON
 | 
					if ! test_have_prereq PYTHON
 | 
				
			||||||
then
 | 
					then
 | 
				
			||||||
	skip_all='skipping remote-hg tests; python not available'
 | 
						skip_all='skipping remote-hg tests; python with mercurial not available'
 | 
				
			||||||
	test_done
 | 
						test_done
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if ! python -c 'import mercurial'
 | 
					if "$PYTHON" -c 'import hggit' > /dev/null 2>&1
 | 
				
			||||||
then
 | 
					then
 | 
				
			||||||
	skip_all='skipping remote-hg tests; mercurial not available'
 | 
						hggit=hggit
 | 
				
			||||||
	test_done
 | 
					elif "$PYTHON" -c 'import hgext.git' > /dev/null 2>&1
 | 
				
			||||||
fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if ! python -c 'import hggit'
 | 
					 | 
				
			||||||
then
 | 
					then
 | 
				
			||||||
 | 
						hggit=hgext.git
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
	skip_all='skipping remote-hg tests; hg-git not available'
 | 
						skip_all='skipping remote-hg tests; hg-git not available'
 | 
				
			||||||
	test_done
 | 
						test_done
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
@@ -69,7 +69,7 @@ hg_push_git () {
 | 
				
			|||||||
	git fetch -q "hg::../$1" 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*' &&
 | 
						git fetch -q "hg::../$1" 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*' &&
 | 
				
			||||||
	git branch -D default &&
 | 
						git branch -D default &&
 | 
				
			||||||
	git checkout -q @{-1} &&
 | 
						git checkout -q @{-1} &&
 | 
				
			||||||
	git branch -q -D tmp 2>/dev/null || true
 | 
						git branch -q -D tmp 2> /dev/null || true
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -82,7 +82,7 @@ hg_push_hg () {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
hg_log () {
 | 
					hg_log () {
 | 
				
			||||||
	hg -R $1 log --graph --debug >log &&
 | 
						hg -R $1 log --graph --debug > log &&
 | 
				
			||||||
	grep -v 'tag: *default/' log
 | 
						grep -v 'tag: *default/' log
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -91,22 +91,24 @@ git_log () {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
setup () {
 | 
					setup () {
 | 
				
			||||||
	(
 | 
						cat > "$HOME"/.hgrc <<-EOF &&
 | 
				
			||||||
	echo "[ui]"
 | 
						[ui]
 | 
				
			||||||
	echo "username = A U Thor <author@example.com>"
 | 
						username = A U Thor <author@example.com>
 | 
				
			||||||
	echo "[defaults]"
 | 
						[defaults]
 | 
				
			||||||
	echo "backout = -d \"0 0\""
 | 
						backout = -d "0 0"
 | 
				
			||||||
	echo "commit = -d \"0 0\""
 | 
						commit = -d "0 0"
 | 
				
			||||||
	echo "debugrawcommit = -d \"0 0\""
 | 
						debugrawcommit = -d "0 0"
 | 
				
			||||||
	echo "tag = -d \"0 0\""
 | 
						tag = -d "0 0"
 | 
				
			||||||
	echo "[extensions]"
 | 
						[extensions]
 | 
				
			||||||
	echo "hgext.bookmarks ="
 | 
						$hggit =
 | 
				
			||||||
	echo "hggit ="
 | 
						graphlog =
 | 
				
			||||||
	echo "graphlog ="
 | 
						[git]
 | 
				
			||||||
	) >>"$HOME"/.hgrc &&
 | 
						debugextrainmessage = 1
 | 
				
			||||||
 | 
						EOF
 | 
				
			||||||
	git config --global receive.denycurrentbranch warn
 | 
						git config --global receive.denycurrentbranch warn
 | 
				
			||||||
	git config --global remote-hg.hg-git-compat true
 | 
						git config --global remote-hg.hg-git-compat true
 | 
				
			||||||
	git config --global remote-hg.track-branches false
 | 
						git config --global remote-hg.track-branches false
 | 
				
			||||||
 | 
						git config --global remote-hg.shared-marks false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	HGEDITOR=true
 | 
						HGEDITOR=true
 | 
				
			||||||
	HGMERGE=true
 | 
						HGMERGE=true
 | 
				
			||||||
@@ -118,13 +120,38 @@ setup () {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
setup
 | 
					setup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_expect_success 'rename' '
 | 
				
			||||||
 | 
						test_when_finished "rm -rf gitrepo* hgrepo*" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						hg init hgrepo1 &&
 | 
				
			||||||
 | 
						cd hgrepo1 &&
 | 
				
			||||||
 | 
						echo alpha > alpha &&
 | 
				
			||||||
 | 
						hg add alpha &&
 | 
				
			||||||
 | 
						hg commit -m "add alpha" &&
 | 
				
			||||||
 | 
						hg mv alpha beta &&
 | 
				
			||||||
 | 
						hg commit -m "rename alpha to beta"
 | 
				
			||||||
 | 
						) &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for x in hg git
 | 
				
			||||||
 | 
						do
 | 
				
			||||||
 | 
							git_clone_$x hgrepo1 gitrepo-$x &&
 | 
				
			||||||
 | 
							hg_clone_$x gitrepo-$x hgrepo2-$x &&
 | 
				
			||||||
 | 
							hg_log hgrepo2-$x > "hg-log-$x" &&
 | 
				
			||||||
 | 
							git_log gitrepo-$x > "git-log-$x"
 | 
				
			||||||
 | 
						done &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						test_cmp hg-log-hg hg-log-git &&
 | 
				
			||||||
 | 
						test_cmp git-log-hg git-log-git
 | 
				
			||||||
 | 
					'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test_expect_success 'executable bit' '
 | 
					test_expect_success 'executable bit' '
 | 
				
			||||||
	test_when_finished "rm -rf gitrepo* hgrepo*" &&
 | 
						test_when_finished "rm -rf gitrepo* hgrepo*" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	(
 | 
						(
 | 
				
			||||||
	git init -q gitrepo &&
 | 
						git init -q gitrepo &&
 | 
				
			||||||
	cd gitrepo &&
 | 
						cd gitrepo &&
 | 
				
			||||||
	echo alpha >alpha &&
 | 
						echo alpha > alpha &&
 | 
				
			||||||
	chmod 0644 alpha &&
 | 
						chmod 0644 alpha &&
 | 
				
			||||||
	git add alpha &&
 | 
						git add alpha &&
 | 
				
			||||||
	git commit -m "add alpha" &&
 | 
						git commit -m "add alpha" &&
 | 
				
			||||||
@@ -144,10 +171,10 @@ test_expect_success 'executable bit' '
 | 
				
			|||||||
		hg_log . &&
 | 
							hg_log . &&
 | 
				
			||||||
		hg manifest -r 1 -v &&
 | 
							hg manifest -r 1 -v &&
 | 
				
			||||||
		hg manifest -v
 | 
							hg manifest -v
 | 
				
			||||||
		) >"output-$x" &&
 | 
							) > "output-$x" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		git_clone_$x hgrepo-$x gitrepo2-$x &&
 | 
							git_clone_$x hgrepo-$x gitrepo2-$x &&
 | 
				
			||||||
		git_log gitrepo2-$x >"log-$x"
 | 
							git_log gitrepo2-$x > "log-$x"
 | 
				
			||||||
	done &&
 | 
						done &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	test_cmp output-hg output-git &&
 | 
						test_cmp output-hg output-git &&
 | 
				
			||||||
@@ -160,7 +187,7 @@ test_expect_success 'symlink' '
 | 
				
			|||||||
	(
 | 
						(
 | 
				
			||||||
	git init -q gitrepo &&
 | 
						git init -q gitrepo &&
 | 
				
			||||||
	cd gitrepo &&
 | 
						cd gitrepo &&
 | 
				
			||||||
	echo alpha >alpha &&
 | 
						echo alpha > alpha &&
 | 
				
			||||||
	git add alpha &&
 | 
						git add alpha &&
 | 
				
			||||||
	git commit -m "add alpha" &&
 | 
						git commit -m "add alpha" &&
 | 
				
			||||||
	ln -s alpha beta &&
 | 
						ln -s alpha beta &&
 | 
				
			||||||
@@ -175,10 +202,10 @@ test_expect_success 'symlink' '
 | 
				
			|||||||
		cd hgrepo-$x &&
 | 
							cd hgrepo-$x &&
 | 
				
			||||||
		hg_log . &&
 | 
							hg_log . &&
 | 
				
			||||||
		hg manifest -v
 | 
							hg manifest -v
 | 
				
			||||||
		) >"output-$x" &&
 | 
							) > "output-$x" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		git_clone_$x hgrepo-$x gitrepo2-$x &&
 | 
							git_clone_$x hgrepo-$x gitrepo2-$x &&
 | 
				
			||||||
		git_log gitrepo2-$x >"log-$x"
 | 
							git_log gitrepo2-$x > "log-$x"
 | 
				
			||||||
	done &&
 | 
						done &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	test_cmp output-hg output-git &&
 | 
						test_cmp output-hg output-git &&
 | 
				
			||||||
@@ -191,19 +218,19 @@ test_expect_success 'merge conflict 1' '
 | 
				
			|||||||
	(
 | 
						(
 | 
				
			||||||
	hg init hgrepo1 &&
 | 
						hg init hgrepo1 &&
 | 
				
			||||||
	cd hgrepo1 &&
 | 
						cd hgrepo1 &&
 | 
				
			||||||
	echo A >afile &&
 | 
						echo A > afile &&
 | 
				
			||||||
	hg add afile &&
 | 
						hg add afile &&
 | 
				
			||||||
	hg ci -m "origin" &&
 | 
						hg ci -m "origin" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	echo B >afile &&
 | 
						echo B > afile &&
 | 
				
			||||||
	hg ci -m "A->B" &&
 | 
						hg ci -m "A->B" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hg up -r0 &&
 | 
						hg up -r0 &&
 | 
				
			||||||
	echo C >afile &&
 | 
						echo C > afile &&
 | 
				
			||||||
	hg ci -m "A->C" &&
 | 
						hg ci -m "A->C" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hg merge -r1 &&
 | 
						hg merge -r1 &&
 | 
				
			||||||
	echo C >afile &&
 | 
						echo C > afile &&
 | 
				
			||||||
	hg resolve -m afile &&
 | 
						hg resolve -m afile &&
 | 
				
			||||||
	hg ci -m "merge to C"
 | 
						hg ci -m "merge to C"
 | 
				
			||||||
	) &&
 | 
						) &&
 | 
				
			||||||
@@ -212,8 +239,8 @@ test_expect_success 'merge conflict 1' '
 | 
				
			|||||||
	do
 | 
						do
 | 
				
			||||||
		git_clone_$x hgrepo1 gitrepo-$x &&
 | 
							git_clone_$x hgrepo1 gitrepo-$x &&
 | 
				
			||||||
		hg_clone_$x gitrepo-$x hgrepo2-$x &&
 | 
							hg_clone_$x gitrepo-$x hgrepo2-$x &&
 | 
				
			||||||
		hg_log hgrepo2-$x >"hg-log-$x" &&
 | 
							hg_log hgrepo2-$x > "hg-log-$x" &&
 | 
				
			||||||
		git_log gitrepo-$x >"git-log-$x"
 | 
							git_log gitrepo-$x > "git-log-$x"
 | 
				
			||||||
	done &&
 | 
						done &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	test_cmp hg-log-hg hg-log-git &&
 | 
						test_cmp hg-log-hg hg-log-git &&
 | 
				
			||||||
@@ -226,19 +253,19 @@ test_expect_success 'merge conflict 2' '
 | 
				
			|||||||
	(
 | 
						(
 | 
				
			||||||
	hg init hgrepo1 &&
 | 
						hg init hgrepo1 &&
 | 
				
			||||||
	cd hgrepo1 &&
 | 
						cd hgrepo1 &&
 | 
				
			||||||
	echo A >afile &&
 | 
						echo A > afile &&
 | 
				
			||||||
	hg add afile &&
 | 
						hg add afile &&
 | 
				
			||||||
	hg ci -m "origin" &&
 | 
						hg ci -m "origin" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	echo B >afile &&
 | 
						echo B > afile &&
 | 
				
			||||||
	hg ci -m "A->B" &&
 | 
						hg ci -m "A->B" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hg up -r0 &&
 | 
						hg up -r0 &&
 | 
				
			||||||
	echo C >afile &&
 | 
						echo C > afile &&
 | 
				
			||||||
	hg ci -m "A->C" &&
 | 
						hg ci -m "A->C" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hg merge -r1 || true &&
 | 
						hg merge -r1 || true &&
 | 
				
			||||||
	echo B >afile &&
 | 
						echo B > afile &&
 | 
				
			||||||
	hg resolve -m afile &&
 | 
						hg resolve -m afile &&
 | 
				
			||||||
	hg ci -m "merge to B"
 | 
						hg ci -m "merge to B"
 | 
				
			||||||
	) &&
 | 
						) &&
 | 
				
			||||||
@@ -247,8 +274,8 @@ test_expect_success 'merge conflict 2' '
 | 
				
			|||||||
	do
 | 
						do
 | 
				
			||||||
		git_clone_$x hgrepo1 gitrepo-$x &&
 | 
							git_clone_$x hgrepo1 gitrepo-$x &&
 | 
				
			||||||
		hg_clone_$x gitrepo-$x hgrepo2-$x &&
 | 
							hg_clone_$x gitrepo-$x hgrepo2-$x &&
 | 
				
			||||||
		hg_log hgrepo2-$x >"hg-log-$x" &&
 | 
							hg_log hgrepo2-$x > "hg-log-$x" &&
 | 
				
			||||||
		git_log gitrepo-$x >"git-log-$x"
 | 
							git_log gitrepo-$x > "git-log-$x"
 | 
				
			||||||
	done &&
 | 
						done &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	test_cmp hg-log-hg hg-log-git &&
 | 
						test_cmp hg-log-hg hg-log-git &&
 | 
				
			||||||
@@ -261,18 +288,18 @@ test_expect_success 'converged merge' '
 | 
				
			|||||||
	(
 | 
						(
 | 
				
			||||||
	hg init hgrepo1 &&
 | 
						hg init hgrepo1 &&
 | 
				
			||||||
	cd hgrepo1 &&
 | 
						cd hgrepo1 &&
 | 
				
			||||||
	echo A >afile &&
 | 
						echo A > afile &&
 | 
				
			||||||
	hg add afile &&
 | 
						hg add afile &&
 | 
				
			||||||
	hg ci -m "origin" &&
 | 
						hg ci -m "origin" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	echo B >afile &&
 | 
						echo B > afile &&
 | 
				
			||||||
	hg ci -m "A->B" &&
 | 
						hg ci -m "A->B" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	echo C >afile &&
 | 
						echo C > afile &&
 | 
				
			||||||
	hg ci -m "B->C" &&
 | 
						hg ci -m "B->C" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hg up -r0 &&
 | 
						hg up -r0 &&
 | 
				
			||||||
	echo C >afile &&
 | 
						echo C > afile &&
 | 
				
			||||||
	hg ci -m "A->C" &&
 | 
						hg ci -m "A->C" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hg merge -r2 || true &&
 | 
						hg merge -r2 || true &&
 | 
				
			||||||
@@ -283,8 +310,8 @@ test_expect_success 'converged merge' '
 | 
				
			|||||||
	do
 | 
						do
 | 
				
			||||||
		git_clone_$x hgrepo1 gitrepo-$x &&
 | 
							git_clone_$x hgrepo1 gitrepo-$x &&
 | 
				
			||||||
		hg_clone_$x gitrepo-$x hgrepo2-$x &&
 | 
							hg_clone_$x gitrepo-$x hgrepo2-$x &&
 | 
				
			||||||
		hg_log hgrepo2-$x >"hg-log-$x" &&
 | 
							hg_log hgrepo2-$x > "hg-log-$x" &&
 | 
				
			||||||
		git_log gitrepo-$x >"git-log-$x"
 | 
							git_log gitrepo-$x > "git-log-$x"
 | 
				
			||||||
	done &&
 | 
						done &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	test_cmp hg-log-hg hg-log-git &&
 | 
						test_cmp hg-log-hg hg-log-git &&
 | 
				
			||||||
@@ -298,22 +325,22 @@ test_expect_success 'encoding' '
 | 
				
			|||||||
	git init -q gitrepo &&
 | 
						git init -q gitrepo &&
 | 
				
			||||||
	cd gitrepo &&
 | 
						cd gitrepo &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	echo alpha >alpha &&
 | 
						echo alpha > alpha &&
 | 
				
			||||||
	git add alpha &&
 | 
						git add alpha &&
 | 
				
			||||||
	git commit -m "add älphà" &&
 | 
						git commit -m "add älphà" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	GIT_AUTHOR_NAME="tést èncödîng" &&
 | 
						GIT_AUTHOR_NAME="tést èncödîng" &&
 | 
				
			||||||
	export GIT_AUTHOR_NAME &&
 | 
						export GIT_AUTHOR_NAME &&
 | 
				
			||||||
	echo beta >beta &&
 | 
						echo beta > beta &&
 | 
				
			||||||
	git add beta &&
 | 
						git add beta &&
 | 
				
			||||||
	git commit -m "add beta" &&
 | 
						git commit -m "add beta" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	echo gamma >gamma &&
 | 
						echo gamma > gamma &&
 | 
				
			||||||
	git add gamma &&
 | 
						git add gamma &&
 | 
				
			||||||
	git commit -m "add gämmâ" &&
 | 
						git commit -m "add gämmâ" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	: TODO git config i18n.commitencoding latin-1 &&
 | 
						: TODO git config i18n.commitencoding latin-1 &&
 | 
				
			||||||
	echo delta >delta &&
 | 
						echo delta > delta &&
 | 
				
			||||||
	git add delta &&
 | 
						git add delta &&
 | 
				
			||||||
	git commit -m "add déltà"
 | 
						git commit -m "add déltà"
 | 
				
			||||||
	) &&
 | 
						) &&
 | 
				
			||||||
@@ -323,8 +350,8 @@ test_expect_success 'encoding' '
 | 
				
			|||||||
		hg_clone_$x gitrepo hgrepo-$x &&
 | 
							hg_clone_$x gitrepo hgrepo-$x &&
 | 
				
			||||||
		git_clone_$x hgrepo-$x gitrepo2-$x &&
 | 
							git_clone_$x hgrepo-$x gitrepo2-$x &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		HGENCODING=utf-8 hg_log hgrepo-$x >"hg-log-$x" &&
 | 
							HGENCODING=utf-8 hg_log hgrepo-$x > "hg-log-$x" &&
 | 
				
			||||||
		git_log gitrepo2-$x >"git-log-$x"
 | 
							git_log gitrepo2-$x > "git-log-$x"
 | 
				
			||||||
	done &&
 | 
						done &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	test_cmp hg-log-hg hg-log-git &&
 | 
						test_cmp hg-log-hg hg-log-git &&
 | 
				
			||||||
@@ -337,14 +364,14 @@ test_expect_success 'file removal' '
 | 
				
			|||||||
	(
 | 
						(
 | 
				
			||||||
	git init -q gitrepo &&
 | 
						git init -q gitrepo &&
 | 
				
			||||||
	cd gitrepo &&
 | 
						cd gitrepo &&
 | 
				
			||||||
	echo alpha >alpha &&
 | 
						echo alpha > alpha &&
 | 
				
			||||||
	git add alpha &&
 | 
						git add alpha &&
 | 
				
			||||||
	git commit -m "add alpha" &&
 | 
						git commit -m "add alpha" &&
 | 
				
			||||||
	echo beta >beta &&
 | 
						echo beta > beta &&
 | 
				
			||||||
	git add beta &&
 | 
						git add beta &&
 | 
				
			||||||
	git commit -m "add beta"
 | 
						git commit -m "add beta"
 | 
				
			||||||
	mkdir foo &&
 | 
						mkdir foo &&
 | 
				
			||||||
	echo blah >foo/bar &&
 | 
						echo blah > foo/bar &&
 | 
				
			||||||
	git add foo &&
 | 
						git add foo &&
 | 
				
			||||||
	git commit -m "add foo" &&
 | 
						git commit -m "add foo" &&
 | 
				
			||||||
	git rm alpha &&
 | 
						git rm alpha &&
 | 
				
			||||||
@@ -361,10 +388,10 @@ test_expect_success 'file removal' '
 | 
				
			|||||||
		hg_log . &&
 | 
							hg_log . &&
 | 
				
			||||||
		hg manifest -r 3 &&
 | 
							hg manifest -r 3 &&
 | 
				
			||||||
		hg manifest
 | 
							hg manifest
 | 
				
			||||||
		) >"output-$x" &&
 | 
							) > "output-$x" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		git_clone_$x hgrepo-$x gitrepo2-$x &&
 | 
							git_clone_$x hgrepo-$x gitrepo2-$x &&
 | 
				
			||||||
		git_log gitrepo2-$x >"log-$x"
 | 
							git_log gitrepo2-$x > "log-$x"
 | 
				
			||||||
	done &&
 | 
						done &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	test_cmp output-hg output-git &&
 | 
						test_cmp output-hg output-git &&
 | 
				
			||||||
@@ -378,12 +405,12 @@ test_expect_success 'git tags' '
 | 
				
			|||||||
	git init -q gitrepo &&
 | 
						git init -q gitrepo &&
 | 
				
			||||||
	cd gitrepo &&
 | 
						cd gitrepo &&
 | 
				
			||||||
	git config receive.denyCurrentBranch ignore &&
 | 
						git config receive.denyCurrentBranch ignore &&
 | 
				
			||||||
	echo alpha >alpha &&
 | 
						echo alpha > alpha &&
 | 
				
			||||||
	git add alpha &&
 | 
						git add alpha &&
 | 
				
			||||||
	git commit -m "add alpha" &&
 | 
						git commit -m "add alpha" &&
 | 
				
			||||||
	git tag alpha &&
 | 
						git tag alpha &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	echo beta >beta &&
 | 
						echo beta > beta &&
 | 
				
			||||||
	git add beta &&
 | 
						git add beta &&
 | 
				
			||||||
	git commit -m "add beta" &&
 | 
						git commit -m "add beta" &&
 | 
				
			||||||
	git tag -a -m "added tag beta" beta
 | 
						git tag -a -m "added tag beta" beta
 | 
				
			||||||
@@ -392,7 +419,7 @@ test_expect_success 'git tags' '
 | 
				
			|||||||
	for x in hg git
 | 
						for x in hg git
 | 
				
			||||||
	do
 | 
						do
 | 
				
			||||||
		hg_clone_$x gitrepo hgrepo-$x &&
 | 
							hg_clone_$x gitrepo hgrepo-$x &&
 | 
				
			||||||
		hg_log hgrepo-$x >"log-$x"
 | 
							hg_log hgrepo-$x > "log-$x"
 | 
				
			||||||
	done &&
 | 
						done &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	test_cmp log-hg log-git
 | 
						test_cmp log-hg log-git
 | 
				
			||||||
@@ -407,7 +434,7 @@ test_expect_success 'hg author' '
 | 
				
			|||||||
		git init -q gitrepo-$x &&
 | 
							git init -q gitrepo-$x &&
 | 
				
			||||||
		cd gitrepo-$x &&
 | 
							cd gitrepo-$x &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		echo alpha >alpha &&
 | 
							echo alpha > alpha &&
 | 
				
			||||||
		git add alpha &&
 | 
							git add alpha &&
 | 
				
			||||||
		git commit -m "add alpha" &&
 | 
							git commit -m "add alpha" &&
 | 
				
			||||||
		git checkout -q -b not-master
 | 
							git checkout -q -b not-master
 | 
				
			||||||
@@ -418,38 +445,38 @@ test_expect_success 'hg author' '
 | 
				
			|||||||
		cd hgrepo-$x &&
 | 
							cd hgrepo-$x &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		hg co master &&
 | 
							hg co master &&
 | 
				
			||||||
		echo beta >beta &&
 | 
							echo beta > beta &&
 | 
				
			||||||
		hg add beta &&
 | 
							hg add beta &&
 | 
				
			||||||
		hg commit -u "test" -m "add beta" &&
 | 
							hg commit -u "test" -m "add beta" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		echo gamma >>beta &&
 | 
							echo gamma >> beta &&
 | 
				
			||||||
		hg commit -u "test <test@example.com> (comment)" -m "modify beta" &&
 | 
							hg commit -u "test <test@example.com> (comment)" -m "modify beta" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		echo gamma >gamma &&
 | 
							echo gamma > gamma &&
 | 
				
			||||||
		hg add gamma &&
 | 
							hg add gamma &&
 | 
				
			||||||
		hg commit -u "<test@example.com>" -m "add gamma" &&
 | 
							hg commit -u "<test@example.com>" -m "add gamma" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		echo delta >delta &&
 | 
							echo delta > delta &&
 | 
				
			||||||
		hg add delta &&
 | 
							hg add delta &&
 | 
				
			||||||
		hg commit -u "name<test@example.com>" -m "add delta" &&
 | 
							hg commit -u "name<test@example.com>" -m "add delta" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		echo epsilon >epsilon &&
 | 
							echo epsilon > epsilon &&
 | 
				
			||||||
		hg add epsilon &&
 | 
							hg add epsilon &&
 | 
				
			||||||
		hg commit -u "name <test@example.com" -m "add epsilon" &&
 | 
							hg commit -u "name <test@example.com" -m "add epsilon" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		echo zeta >zeta &&
 | 
							echo zeta > zeta &&
 | 
				
			||||||
		hg add zeta &&
 | 
							hg add zeta &&
 | 
				
			||||||
		hg commit -u " test " -m "add zeta" &&
 | 
							hg commit -u " test " -m "add zeta" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		echo eta >eta &&
 | 
							echo eta > eta &&
 | 
				
			||||||
		hg add eta &&
 | 
							hg add eta &&
 | 
				
			||||||
		hg commit -u "test < test@example.com >" -m "add eta" &&
 | 
							hg commit -u "test < test@example.com >" -m "add eta" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		echo theta >theta &&
 | 
							echo theta > theta &&
 | 
				
			||||||
		hg add theta &&
 | 
							hg add theta &&
 | 
				
			||||||
		hg commit -u "test >test@example.com>" -m "add theta" &&
 | 
							hg commit -u "test >test@example.com>" -m "add theta" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		echo iota >iota &&
 | 
							echo iota > iota &&
 | 
				
			||||||
		hg add iota &&
 | 
							hg add iota &&
 | 
				
			||||||
		hg commit -u "test <test <at> example <dot> com>" -m "add iota"
 | 
							hg commit -u "test <test <at> example <dot> com>" -m "add iota"
 | 
				
			||||||
		) &&
 | 
							) &&
 | 
				
			||||||
@@ -457,8 +484,8 @@ test_expect_success 'hg author' '
 | 
				
			|||||||
		hg_push_$x hgrepo-$x gitrepo-$x &&
 | 
							hg_push_$x hgrepo-$x gitrepo-$x &&
 | 
				
			||||||
		hg_clone_$x gitrepo-$x hgrepo2-$x &&
 | 
							hg_clone_$x gitrepo-$x hgrepo2-$x &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		hg_log hgrepo2-$x >"hg-log-$x" &&
 | 
							hg_log hgrepo2-$x > "hg-log-$x" &&
 | 
				
			||||||
		git_log gitrepo-$x >"git-log-$x"
 | 
							git_log gitrepo-$x > "git-log-$x"
 | 
				
			||||||
	done &&
 | 
						done &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	test_cmp hg-log-hg hg-log-git &&
 | 
						test_cmp hg-log-hg hg-log-git &&
 | 
				
			||||||
@@ -474,7 +501,7 @@ test_expect_success 'hg branch' '
 | 
				
			|||||||
		git init -q gitrepo-$x &&
 | 
							git init -q gitrepo-$x &&
 | 
				
			||||||
		cd gitrepo-$x &&
 | 
							cd gitrepo-$x &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		echo alpha >alpha &&
 | 
							echo alpha > alpha &&
 | 
				
			||||||
		git add alpha &&
 | 
							git add alpha &&
 | 
				
			||||||
		git commit -q -m "add alpha" &&
 | 
							git commit -q -m "add alpha" &&
 | 
				
			||||||
		git checkout -q -b not-master
 | 
							git checkout -q -b not-master
 | 
				
			||||||
@@ -494,8 +521,8 @@ test_expect_success 'hg branch' '
 | 
				
			|||||||
		hg_push_$x hgrepo-$x gitrepo-$x &&
 | 
							hg_push_$x hgrepo-$x gitrepo-$x &&
 | 
				
			||||||
		hg_clone_$x gitrepo-$x hgrepo2-$x &&
 | 
							hg_clone_$x gitrepo-$x hgrepo2-$x &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		hg_log hgrepo2-$x >"hg-log-$x" &&
 | 
							hg_log hgrepo2-$x > "hg-log-$x" &&
 | 
				
			||||||
		git_log gitrepo-$x >"git-log-$x"
 | 
							git_log gitrepo-$x > "git-log-$x"
 | 
				
			||||||
	done &&
 | 
						done &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	test_cmp hg-log-hg hg-log-git &&
 | 
						test_cmp hg-log-hg hg-log-git &&
 | 
				
			||||||
@@ -511,7 +538,7 @@ test_expect_success 'hg tags' '
 | 
				
			|||||||
		git init -q gitrepo-$x &&
 | 
							git init -q gitrepo-$x &&
 | 
				
			||||||
		cd gitrepo-$x &&
 | 
							cd gitrepo-$x &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		echo alpha >alpha &&
 | 
							echo alpha > alpha &&
 | 
				
			||||||
		git add alpha &&
 | 
							git add alpha &&
 | 
				
			||||||
		git commit -m "add alpha" &&
 | 
							git commit -m "add alpha" &&
 | 
				
			||||||
		git checkout -q -b not-master
 | 
							git checkout -q -b not-master
 | 
				
			||||||
@@ -532,7 +559,7 @@ test_expect_success 'hg tags' '
 | 
				
			|||||||
		git --git-dir=gitrepo-$x/.git tag -l &&
 | 
							git --git-dir=gitrepo-$x/.git tag -l &&
 | 
				
			||||||
		hg_log hgrepo2-$x &&
 | 
							hg_log hgrepo2-$x &&
 | 
				
			||||||
		cat hgrepo2-$x/.hgtags
 | 
							cat hgrepo2-$x/.hgtags
 | 
				
			||||||
		) >"output-$x"
 | 
							) > "output-$x"
 | 
				
			||||||
	done &&
 | 
						done &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	test_cmp output-hg output-git
 | 
						test_cmp output-hg output-git
 | 
				
			||||||
							
								
								
									
										314
									
								
								test/main-push.t
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										314
									
								
								test/main-push.t
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,314 @@
 | 
				
			|||||||
 | 
					CAPABILITY_PUSH=t
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test -n "$TEST_DIRECTORY" || TEST_DIRECTORY=$(dirname $0)/
 | 
				
			||||||
 | 
					. "$TEST_DIRECTORY"/main.t
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# .. and some push mode only specific tests
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_expect_success 'remote delete bookmark' '
 | 
				
			||||||
 | 
						test_when_finished "rm -rf hgrepo* gitrepo*" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						hg init hgrepo &&
 | 
				
			||||||
 | 
						cd hgrepo &&
 | 
				
			||||||
 | 
						echo zero > content &&
 | 
				
			||||||
 | 
						hg add content &&
 | 
				
			||||||
 | 
						hg commit -m zero
 | 
				
			||||||
 | 
						hg bookmark feature-a
 | 
				
			||||||
 | 
						) &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						git clone "hg::hgrepo" gitrepo &&
 | 
				
			||||||
 | 
						check_bookmark hgrepo feature-a zero &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						cd gitrepo &&
 | 
				
			||||||
 | 
						git push --quiet origin :feature-a
 | 
				
			||||||
 | 
						) &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						check_bookmark hgrepo feature-a ''
 | 
				
			||||||
 | 
					'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_expect_success 'source:dest bookmark' '
 | 
				
			||||||
 | 
						test_when_finished "rm -rf hgrepo gitrepo" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						hg init hgrepo &&
 | 
				
			||||||
 | 
						cd hgrepo &&
 | 
				
			||||||
 | 
						echo zero > content &&
 | 
				
			||||||
 | 
						hg add content &&
 | 
				
			||||||
 | 
						hg commit -m zero
 | 
				
			||||||
 | 
						) &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						git clone "hg::hgrepo" gitrepo &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						cd gitrepo &&
 | 
				
			||||||
 | 
						echo one > content &&
 | 
				
			||||||
 | 
						git commit -a -m one &&
 | 
				
			||||||
 | 
						git push --quiet origin master:feature-b &&
 | 
				
			||||||
 | 
						git push --quiet origin master^:refs/heads/feature-a
 | 
				
			||||||
 | 
						) &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						check_bookmark hgrepo feature-a zero &&
 | 
				
			||||||
 | 
						check_bookmark hgrepo feature-b one &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						cd gitrepo &&
 | 
				
			||||||
 | 
						git push --quiet origin master:feature-a
 | 
				
			||||||
 | 
						) &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						check_bookmark hgrepo feature-a one
 | 
				
			||||||
 | 
					'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					setup_check_hg_commits_repo () {
 | 
				
			||||||
 | 
					        (
 | 
				
			||||||
 | 
						rm -rf hgrepo* &&
 | 
				
			||||||
 | 
						hg init hgrepo &&
 | 
				
			||||||
 | 
						cd hgrepo &&
 | 
				
			||||||
 | 
						echo zero > content &&
 | 
				
			||||||
 | 
						hg add content &&
 | 
				
			||||||
 | 
						hg commit -m zero
 | 
				
			||||||
 | 
						) &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						git clone "hg::hgrepo" gitrepo &&
 | 
				
			||||||
 | 
						hg clone hgrepo hgrepo.second &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						cd gitrepo &&
 | 
				
			||||||
 | 
						git remote add second hg::../hgrepo.second &&
 | 
				
			||||||
 | 
						git fetch second
 | 
				
			||||||
 | 
						) &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						cd hgrepo &&
 | 
				
			||||||
 | 
						echo one > content &&
 | 
				
			||||||
 | 
						hg commit -m one &&
 | 
				
			||||||
 | 
						echo two > content &&
 | 
				
			||||||
 | 
						hg commit -m two &&
 | 
				
			||||||
 | 
						echo three > content &&
 | 
				
			||||||
 | 
						hg commit -m three &&
 | 
				
			||||||
 | 
						hg move content content-move &&
 | 
				
			||||||
 | 
						hg commit -m moved &&
 | 
				
			||||||
 | 
						hg move content-move content &&
 | 
				
			||||||
 | 
						hg commit -m restored
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# a shared bag would make all of the following pretty trivial
 | 
				
			||||||
 | 
					git config --global remote-hg.shared-marks false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					git config --global remote-hg.check-hg-commits fail
 | 
				
			||||||
 | 
					test_expect_success 'check-hg-commits with fail mode' '
 | 
				
			||||||
 | 
						test_when_finished "rm -rf gitrepo* hgrepo*" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setup_check_hg_commits_repo &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						cd gitrepo &&
 | 
				
			||||||
 | 
						git fetch origin &&
 | 
				
			||||||
 | 
						git reset --hard origin/master &&
 | 
				
			||||||
 | 
						! git push second master 2>../error
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cat error &&
 | 
				
			||||||
 | 
						grep rejected error | grep hg
 | 
				
			||||||
 | 
					'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					git config --global remote-hg.check-hg-commits push
 | 
				
			||||||
 | 
					# codepath for push is slightly different depending on shared proxy involved
 | 
				
			||||||
 | 
					# so tweak to test both
 | 
				
			||||||
 | 
					check_hg_commits_push () {
 | 
				
			||||||
 | 
						test_when_finished "rm -rf gitrepo* hgrepo*" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setup_check_hg_commits_repo &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						cd gitrepo &&
 | 
				
			||||||
 | 
						git fetch origin &&
 | 
				
			||||||
 | 
						git reset --hard origin/master &&
 | 
				
			||||||
 | 
						git push second master 2> ../error
 | 
				
			||||||
 | 
						) &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cat error &&
 | 
				
			||||||
 | 
						grep "hg changeset" error &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hg log -R hgrepo > expected &&
 | 
				
			||||||
 | 
						hg log -R hgrepo.second | grep -v bookmark > actual &&
 | 
				
			||||||
 | 
						test_cmp expected actual
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unset GIT_REMOTE_HG_TEST_REMOTE
 | 
				
			||||||
 | 
					test_expect_success 'check-hg-commits with push mode - no local proxy' '
 | 
				
			||||||
 | 
						check_hg_commits_push
 | 
				
			||||||
 | 
					'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GIT_REMOTE_HG_TEST_REMOTE=1 &&
 | 
				
			||||||
 | 
					export GIT_REMOTE_HG_TEST_REMOTE
 | 
				
			||||||
 | 
					test_expect_success 'check-hg-commits with push mode - with local proxy' '
 | 
				
			||||||
 | 
						check_hg_commits_push
 | 
				
			||||||
 | 
					'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					setup_check_shared_marks_repo () {
 | 
				
			||||||
 | 
					        (
 | 
				
			||||||
 | 
						rm -rf hgrepo* &&
 | 
				
			||||||
 | 
						hg init hgrepo &&
 | 
				
			||||||
 | 
						cd hgrepo &&
 | 
				
			||||||
 | 
						echo zero > content &&
 | 
				
			||||||
 | 
						hg add content &&
 | 
				
			||||||
 | 
						hg commit -m zero
 | 
				
			||||||
 | 
						) &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						git clone "hg::hgrepo" gitrepo &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						cd gitrepo &&
 | 
				
			||||||
 | 
						git remote add second hg::../hgrepo &&
 | 
				
			||||||
 | 
						git fetch second
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					check_marks () {
 | 
				
			||||||
 | 
						dir=$1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ls -al $dir &&
 | 
				
			||||||
 | 
						if test "$2" = "y"
 | 
				
			||||||
 | 
						then
 | 
				
			||||||
 | 
							test -f $dir/marks-git && test -f $dir/marks-hg
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							test ! -f $dir/marks-git && test ! -f $dir/marks-hg
 | 
				
			||||||
 | 
						fi
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# cleanup setting
 | 
				
			||||||
 | 
					git config --global --unset remote-hg.shared-marks
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_expect_success 'shared-marks unset' '
 | 
				
			||||||
 | 
						test_when_finished "rm -rf gitrepo* hgrepo*" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setup_check_shared_marks_repo &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						cd gitrepo &&
 | 
				
			||||||
 | 
						check_marks .git/hg y &&
 | 
				
			||||||
 | 
						check_marks .git/hg/origin n &&
 | 
				
			||||||
 | 
						check_marks .git/hg/second n
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_expect_success 'shared-marks set to unset' '
 | 
				
			||||||
 | 
						test_when_finished "rm -rf gitrepo* hgrepo*" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						git config --global remote-hg.shared-marks true &&
 | 
				
			||||||
 | 
						setup_check_shared_marks_repo &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						cd gitrepo &&
 | 
				
			||||||
 | 
						check_marks .git/hg y &&
 | 
				
			||||||
 | 
						check_marks .git/hg/origin n &&
 | 
				
			||||||
 | 
						check_marks .git/hg/second n
 | 
				
			||||||
 | 
						) &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						git config --global remote-hg.shared-marks false &&
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
							cd gitrepo &&
 | 
				
			||||||
 | 
							git fetch origin &&
 | 
				
			||||||
 | 
							check_marks .git/hg n &&
 | 
				
			||||||
 | 
							check_marks .git/hg/origin y &&
 | 
				
			||||||
 | 
							check_marks .git/hg/second y
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_expect_success 'shared-marks unset to set' '
 | 
				
			||||||
 | 
						test_when_finished "rm -rf gitrepo* hgrepo*" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						git config --global remote-hg.shared-marks false &&
 | 
				
			||||||
 | 
						setup_check_shared_marks_repo &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						cd gitrepo &&
 | 
				
			||||||
 | 
						check_marks .git/hg n &&
 | 
				
			||||||
 | 
						check_marks .git/hg/origin y &&
 | 
				
			||||||
 | 
						check_marks .git/hg/second y
 | 
				
			||||||
 | 
						) &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						git config --global --unset remote-hg.shared-marks &&
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
							cd gitrepo &&
 | 
				
			||||||
 | 
							git fetch origin &&
 | 
				
			||||||
 | 
							check_marks .git/hg n &&
 | 
				
			||||||
 | 
							check_marks .git/hg/origin y &&
 | 
				
			||||||
 | 
							check_marks .git/hg/second y
 | 
				
			||||||
 | 
						) &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						git config --global remote-hg.shared-marks true &&
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
							cd gitrepo &&
 | 
				
			||||||
 | 
							git fetch origin &&
 | 
				
			||||||
 | 
							check_marks .git/hg y &&
 | 
				
			||||||
 | 
							check_marks .git/hg/origin n &&
 | 
				
			||||||
 | 
							check_marks .git/hg/second n
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_expect_success 'push with renamed executable preserves executable bit' '
 | 
				
			||||||
 | 
						test_when_finished "rm -rf hgrepo gitrepo*" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hg init hgrepo &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						git init gitrepo &&
 | 
				
			||||||
 | 
						cd gitrepo &&
 | 
				
			||||||
 | 
						git remote add origin "hg::../hgrepo" &&
 | 
				
			||||||
 | 
						echo one > content &&
 | 
				
			||||||
 | 
						chmod a+x content &&
 | 
				
			||||||
 | 
						git add content &&
 | 
				
			||||||
 | 
						git commit -a -m one &&
 | 
				
			||||||
 | 
						git mv content content2 &&
 | 
				
			||||||
 | 
						git commit -a -m two &&
 | 
				
			||||||
 | 
						git push origin master
 | 
				
			||||||
 | 
						) &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						umask 0 &&
 | 
				
			||||||
 | 
						cd hgrepo &&
 | 
				
			||||||
 | 
						hg update &&
 | 
				
			||||||
 | 
						stat content2 >expected &&
 | 
				
			||||||
 | 
						grep -- -r.xr.xr.x expected
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_expect_success 'push with submodule' '
 | 
				
			||||||
 | 
						test_when_finished "rm -rf sub hgrepo gitrepo*" &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hg init hgrepo &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						git init sub &&
 | 
				
			||||||
 | 
						cd sub &&
 | 
				
			||||||
 | 
						: >empty &&
 | 
				
			||||||
 | 
						git add empty &&
 | 
				
			||||||
 | 
						git commit -m init
 | 
				
			||||||
 | 
						) &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						git init gitrepo &&
 | 
				
			||||||
 | 
						cd gitrepo &&
 | 
				
			||||||
 | 
						git submodule add ../sub sub &&
 | 
				
			||||||
 | 
						git remote add origin "hg::../hgrepo" &&
 | 
				
			||||||
 | 
						git commit -a -m sub &&
 | 
				
			||||||
 | 
						git push origin master
 | 
				
			||||||
 | 
						) &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
						cd hgrepo &&
 | 
				
			||||||
 | 
						hg update &&
 | 
				
			||||||
 | 
						expected="[git-remote-hg: skipped import of submodule at $(git -C ../sub rev-parse HEAD)]"
 | 
				
			||||||
 | 
						test "$expected" = "$(cat sub)"
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# cleanup setting
 | 
				
			||||||
 | 
					git config --global --unset remote-hg.shared-marks
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_done
 | 
				
			||||||
							
								
								
									
										1334
									
								
								test/main.t
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										1334
									
								
								test/main.t
									
									
									
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										394
									
								
								test/sharness.sh
									
									
									
									
									
								
							
							
						
						
									
										394
									
								
								test/sharness.sh
									
									
									
									
									
								
							@@ -18,33 +18,80 @@
 | 
				
			|||||||
# along with this program.  If not, see http://www.gnu.org/licenses/ .
 | 
					# along with this program.  If not, see http://www.gnu.org/licenses/ .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Public: Current version of Sharness.
 | 
					# Public: Current version of Sharness.
 | 
				
			||||||
SHARNESS_VERSION="0.3.0"
 | 
					SHARNESS_VERSION="1.1.0"
 | 
				
			||||||
export SHARNESS_VERSION
 | 
					export SHARNESS_VERSION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Public: The file extension for tests.  By default, it is set to "t".
 | 
					# Public: The file extension for tests.  By default, it is set to "t".
 | 
				
			||||||
: ${SHARNESS_TEST_EXTENSION:=t}
 | 
					: "${SHARNESS_TEST_EXTENSION:=t}"
 | 
				
			||||||
export SHARNESS_TEST_EXTENSION
 | 
					export SHARNESS_TEST_EXTENSION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Keep the original TERM for say_color
 | 
					# Public: Root directory containing tests. Tests can override this variable,
 | 
				
			||||||
ORIGINAL_TERM=$TERM
 | 
					# e.g. for testing Sharness itself.
 | 
				
			||||||
 | 
					if test -z "$SHARNESS_TEST_DIRECTORY"
 | 
				
			||||||
 | 
					then
 | 
				
			||||||
 | 
						SHARNESS_TEST_DIRECTORY=$(pwd)
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
						# ensure that SHARNESS_TEST_DIRECTORY is an absolute path so that it
 | 
				
			||||||
 | 
						# is valid even if the current working directory is changed
 | 
				
			||||||
 | 
						SHARNESS_TEST_DIRECTORY=$(cd "$SHARNESS_TEST_DIRECTORY" && pwd) || exit 1
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					export SHARNESS_TEST_DIRECTORY
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if test -z "$SHARNESS_TEST_OUTPUT_DIRECTORY"
 | 
				
			||||||
 | 
					then
 | 
				
			||||||
 | 
						# Similarly, override this to store the test-results subdir
 | 
				
			||||||
 | 
						# elsewhere
 | 
				
			||||||
 | 
						SHARNESS_TEST_OUTPUT_DIRECTORY=$SHARNESS_TEST_DIRECTORY
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#  Reset TERM to original terminal if found, otherwise save original TERM
 | 
				
			||||||
 | 
					[ "x" = "x$SHARNESS_ORIG_TERM" ] &&
 | 
				
			||||||
 | 
							SHARNESS_ORIG_TERM="$TERM" ||
 | 
				
			||||||
 | 
							TERM="$SHARNESS_ORIG_TERM"
 | 
				
			||||||
 | 
					# Public: The unsanitized TERM under which sharness is originally run
 | 
				
			||||||
 | 
					export SHARNESS_ORIG_TERM
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Export SHELL_PATH
 | 
				
			||||||
 | 
					: "${SHELL_PATH:=$SHELL}"
 | 
				
			||||||
 | 
					export SHELL_PATH
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# if --tee was passed, write the output not only to the terminal, but
 | 
				
			||||||
 | 
					# additionally to the file test-results/$BASENAME.out, too.
 | 
				
			||||||
 | 
					case "$SHARNESS_TEST_TEE_STARTED, $* " in
 | 
				
			||||||
 | 
					done,*)
 | 
				
			||||||
 | 
						# do not redirect again
 | 
				
			||||||
 | 
						;;
 | 
				
			||||||
 | 
					*' --tee '*|*' --verbose-log '*)
 | 
				
			||||||
 | 
						mkdir -p "$SHARNESS_TEST_OUTPUT_DIRECTORY/test-results"
 | 
				
			||||||
 | 
						BASE="$SHARNESS_TEST_OUTPUT_DIRECTORY/test-results/$(basename "$0" ".$SHARNESS_TEST_EXTENSION")"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						# Make this filename available to the sub-process in case it is using
 | 
				
			||||||
 | 
						# --verbose-log.
 | 
				
			||||||
 | 
						SHARNESS_TEST_TEE_OUTPUT_FILE="$BASE.out"
 | 
				
			||||||
 | 
						export SHARNESS_TEST_TEE_OUTPUT_FILE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						# Truncate before calling "tee -a" to get rid of the results
 | 
				
			||||||
 | 
						# from any previous runs.
 | 
				
			||||||
 | 
						: >"$SHARNESS_TEST_TEE_OUTPUT_FILE"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(SHARNESS_TEST_TEE_STARTED="done" ${SHELL_PATH} "$0" "$@" 2>&1;
 | 
				
			||||||
 | 
						 echo $? >"$BASE.exit") | tee -a "$SHARNESS_TEST_TEE_OUTPUT_FILE"
 | 
				
			||||||
 | 
						test "$(cat "$BASE.exit")" = 0
 | 
				
			||||||
 | 
						exit
 | 
				
			||||||
 | 
						;;
 | 
				
			||||||
 | 
					esac
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# For repeatability, reset the environment to a known state.
 | 
					# For repeatability, reset the environment to a known state.
 | 
				
			||||||
 | 
					# TERM is sanitized below, after saving color control sequences.
 | 
				
			||||||
LANG=C
 | 
					LANG=C
 | 
				
			||||||
LC_ALL=C
 | 
					LC_ALL=C
 | 
				
			||||||
PAGER=cat
 | 
					PAGER="cat"
 | 
				
			||||||
TZ=UTC
 | 
					TZ=UTC
 | 
				
			||||||
TERM=dumb
 | 
					 | 
				
			||||||
EDITOR=:
 | 
					EDITOR=:
 | 
				
			||||||
export LANG LC_ALL PAGER TZ TERM EDITOR
 | 
					export LANG LC_ALL PAGER TZ EDITOR
 | 
				
			||||||
unset VISUAL CDPATH GREP_OPTIONS
 | 
					unset VISUAL CDPATH GREP_OPTIONS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Line feed
 | 
					[ "x$TERM" != "xdumb" ] && (
 | 
				
			||||||
LF='
 | 
					 | 
				
			||||||
'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[ "x$ORIGINAL_TERM" != "xdumb" ] && (
 | 
					 | 
				
			||||||
		TERM=$ORIGINAL_TERM &&
 | 
					 | 
				
			||||||
		export TERM &&
 | 
					 | 
				
			||||||
		[ -t 1 ] &&
 | 
							[ -t 1 ] &&
 | 
				
			||||||
		tput bold >/dev/null 2>&1 &&
 | 
							tput bold >/dev/null 2>&1 &&
 | 
				
			||||||
		tput setaf 1 >/dev/null 2>&1 &&
 | 
							tput setaf 1 >/dev/null 2>&1 &&
 | 
				
			||||||
@@ -60,6 +107,8 @@ while test "$#" -ne 0; do
 | 
				
			|||||||
		immediate=t; shift ;;
 | 
							immediate=t; shift ;;
 | 
				
			||||||
	-l|--l|--lo|--lon|--long|--long-|--long-t|--long-te|--long-tes|--long-test|--long-tests)
 | 
						-l|--l|--lo|--lon|--long|--long-|--long-t|--long-te|--long-tes|--long-test|--long-tests)
 | 
				
			||||||
		TEST_LONG=t; export TEST_LONG; shift ;;
 | 
							TEST_LONG=t; export TEST_LONG; shift ;;
 | 
				
			||||||
 | 
						--in|--int|--inte|--inter|--intera|--interac|--interact|--interacti|--interactiv|--interactive|--interactive-|--interactive-t|--interactive-te|--interactive-tes|--interactive-test|--interactive-tests):
 | 
				
			||||||
 | 
							TEST_INTERACTIVE=t; export TEST_INTERACTIVE; verbose=t; shift ;;
 | 
				
			||||||
	-h|--h|--he|--hel|--help)
 | 
						-h|--h|--he|--hel|--help)
 | 
				
			||||||
		help=t; shift ;;
 | 
							help=t; shift ;;
 | 
				
			||||||
	-v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)
 | 
						-v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)
 | 
				
			||||||
@@ -68,49 +117,69 @@ while test "$#" -ne 0; do
 | 
				
			|||||||
		# Ignore --quiet under a TAP::Harness. Saying how many tests
 | 
							# Ignore --quiet under a TAP::Harness. Saying how many tests
 | 
				
			||||||
		# passed without the ok/not ok details is always an error.
 | 
							# passed without the ok/not ok details is always an error.
 | 
				
			||||||
		test -z "$HARNESS_ACTIVE" && quiet=t; shift ;;
 | 
							test -z "$HARNESS_ACTIVE" && quiet=t; shift ;;
 | 
				
			||||||
 | 
						--chain-lint)
 | 
				
			||||||
 | 
							chain_lint=t; shift ;;
 | 
				
			||||||
 | 
						--no-chain-lint)
 | 
				
			||||||
 | 
							chain_lint=; shift ;;
 | 
				
			||||||
	--no-color)
 | 
						--no-color)
 | 
				
			||||||
		color=; shift ;;
 | 
							color=; shift ;;
 | 
				
			||||||
 | 
						--tee)
 | 
				
			||||||
 | 
							shift ;; # was handled already
 | 
				
			||||||
	--root=*)
 | 
						--root=*)
 | 
				
			||||||
		root=$(expr "z$1" : 'z[^=]*=\(.*\)')
 | 
							root=$(expr "z$1" : 'z[^=]*=\(.*\)')
 | 
				
			||||||
		shift ;;
 | 
							shift ;;
 | 
				
			||||||
 | 
						--verbose-log)
 | 
				
			||||||
 | 
							verbose_log=t
 | 
				
			||||||
 | 
							shift ;;
 | 
				
			||||||
	*)
 | 
						*)
 | 
				
			||||||
		echo "error: unknown test option '$1'" >&2; exit 1 ;;
 | 
							echo "error: unknown test option '$1'" >&2; exit 1 ;;
 | 
				
			||||||
	esac
 | 
						esac
 | 
				
			||||||
done
 | 
					done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if test -n "$color"; then
 | 
					if test -n "$color"; then
 | 
				
			||||||
 | 
						# Save the color control sequences now rather than run tput
 | 
				
			||||||
 | 
						# each time say_color() is called.  This is done for two
 | 
				
			||||||
 | 
						# reasons:
 | 
				
			||||||
 | 
						#   * TERM will be changed to dumb
 | 
				
			||||||
 | 
						#   * HOME will be changed to a temporary directory and tput
 | 
				
			||||||
 | 
						#     might need to read ~/.terminfo from the original HOME
 | 
				
			||||||
 | 
						#     directory to get the control sequences
 | 
				
			||||||
 | 
						# Note:  This approach assumes the control sequences don't end
 | 
				
			||||||
 | 
						# in a newline for any terminal of interest (command
 | 
				
			||||||
 | 
						# substitutions strip trailing newlines).  Given that most
 | 
				
			||||||
 | 
						# (all?) terminals in common use are related to ECMA-48, this
 | 
				
			||||||
 | 
						# shouldn't be a problem.
 | 
				
			||||||
 | 
						say_color_error=$(tput bold; tput setaf 1) # bold red
 | 
				
			||||||
 | 
						say_color_skip=$(tput setaf 4) # blue
 | 
				
			||||||
 | 
						say_color_warn=$(tput setaf 3) # brown/yellow
 | 
				
			||||||
 | 
						say_color_pass=$(tput setaf 2) # green
 | 
				
			||||||
 | 
						say_color_info=$(tput setaf 6) # cyan
 | 
				
			||||||
 | 
						say_color_reset=$(tput sgr0)
 | 
				
			||||||
 | 
						say_color_raw="" # no formatting for normal text
 | 
				
			||||||
	say_color() {
 | 
						say_color() {
 | 
				
			||||||
		(
 | 
							test -z "$1" && test -n "$quiet" && return
 | 
				
			||||||
		TERM=$ORIGINAL_TERM
 | 
					 | 
				
			||||||
		export TERM
 | 
					 | 
				
			||||||
		case "$1" in
 | 
							case "$1" in
 | 
				
			||||||
		error)
 | 
								error) say_color_color=$say_color_error ;;
 | 
				
			||||||
			tput bold; tput setaf 1;; # bold red
 | 
								skip) say_color_color=$say_color_skip ;;
 | 
				
			||||||
		skip)
 | 
								warn) say_color_color=$say_color_warn ;;
 | 
				
			||||||
			tput setaf 4;; # blue
 | 
								pass) say_color_color=$say_color_pass ;;
 | 
				
			||||||
		warn)
 | 
								info) say_color_color=$say_color_info ;;
 | 
				
			||||||
			tput setaf 3;; # brown/yellow
 | 
								*) say_color_color=$say_color_raw ;;
 | 
				
			||||||
		pass)
 | 
					 | 
				
			||||||
			tput setaf 2;; # green
 | 
					 | 
				
			||||||
		info)
 | 
					 | 
				
			||||||
			tput setaf 6;; # cyan
 | 
					 | 
				
			||||||
		*)
 | 
					 | 
				
			||||||
			test -n "$quiet" && return;;
 | 
					 | 
				
			||||||
		esac
 | 
							esac
 | 
				
			||||||
		shift
 | 
							shift
 | 
				
			||||||
		printf "%s" "$*"
 | 
							printf '%s%s%s\n' "$say_color_color" "$*" "$say_color_reset"
 | 
				
			||||||
		tput sgr0
 | 
					 | 
				
			||||||
		echo
 | 
					 | 
				
			||||||
		)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
else
 | 
					else
 | 
				
			||||||
	say_color() {
 | 
						say_color() {
 | 
				
			||||||
		test -z "$1" && test -n "$quiet" && return
 | 
							test -z "$1" && test -n "$quiet" && return
 | 
				
			||||||
		shift
 | 
							shift
 | 
				
			||||||
		printf "%s\n" "$*"
 | 
							printf '%s\n' "$*"
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TERM=dumb
 | 
				
			||||||
 | 
					export TERM
 | 
				
			||||||
 | 
					
 | 
				
			||||||
error() {
 | 
					error() {
 | 
				
			||||||
	say_color error "error: $*"
 | 
						say_color error "error: $*"
 | 
				
			||||||
	EXIT_OK=t
 | 
						EXIT_OK=t
 | 
				
			||||||
@@ -121,7 +190,7 @@ say() {
 | 
				
			|||||||
	say_color info "$*"
 | 
						say_color info "$*"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test -n "$test_description" || error "Test script did not set test_description."
 | 
					test -n "${test_description:-}" || error "Test script did not set test_description."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if test "$help" = "t"; then
 | 
					if test "$help" = "t"; then
 | 
				
			||||||
	echo "$test_description"
 | 
						echo "$test_description"
 | 
				
			||||||
@@ -130,7 +199,11 @@ fi
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
exec 5>&1
 | 
					exec 5>&1
 | 
				
			||||||
exec 6<&0
 | 
					exec 6<&0
 | 
				
			||||||
if test "$verbose" = "t"; then
 | 
					if test "$verbose_log" = "t"
 | 
				
			||||||
 | 
					then
 | 
				
			||||||
 | 
						exec 3>>"$SHARNESS_TEST_TEE_OUTPUT_FILE" 4>&3
 | 
				
			||||||
 | 
					elif test "$verbose" = "t"
 | 
				
			||||||
 | 
					then
 | 
				
			||||||
	exec 4>&2 3>&1
 | 
						exec 4>&2 3>&1
 | 
				
			||||||
else
 | 
					else
 | 
				
			||||||
	exec 4>/dev/null 3>/dev/null
 | 
						exec 4>/dev/null 3>/dev/null
 | 
				
			||||||
@@ -161,7 +234,7 @@ trap 'die' EXIT
 | 
				
			|||||||
# implicitly by specifying the prerequisite name in calls to test_expect_success
 | 
					# implicitly by specifying the prerequisite name in calls to test_expect_success
 | 
				
			||||||
# or test_expect_failure.
 | 
					# or test_expect_failure.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# $1 - Name of prerequiste (a simple word, in all capital letters by convention)
 | 
					# $1 - Name of prerequisite (a simple word, in all capital letters by convention)
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# Examples
 | 
					# Examples
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
@@ -198,7 +271,7 @@ test_have_prereq() {
 | 
				
			|||||||
	# prerequisites can be concatenated with ','
 | 
						# prerequisites can be concatenated with ','
 | 
				
			||||||
	save_IFS=$IFS
 | 
						save_IFS=$IFS
 | 
				
			||||||
	IFS=,
 | 
						IFS=,
 | 
				
			||||||
	set -- $*
 | 
						set -- $@
 | 
				
			||||||
	IFS=$save_IFS
 | 
						IFS=$save_IFS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	total_prereq=0
 | 
						total_prereq=0
 | 
				
			||||||
@@ -215,7 +288,7 @@ test_have_prereq() {
 | 
				
			|||||||
			negative_prereq=
 | 
								negative_prereq=
 | 
				
			||||||
		esac
 | 
							esac
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		total_prereq=$(($total_prereq + 1))
 | 
							total_prereq=$((total_prereq + 1))
 | 
				
			||||||
		case "$satisfied_prereq" in
 | 
							case "$satisfied_prereq" in
 | 
				
			||||||
		*" $prerequisite "*)
 | 
							*" $prerequisite "*)
 | 
				
			||||||
			satisfied_this_prereq=t
 | 
								satisfied_this_prereq=t
 | 
				
			||||||
@@ -226,7 +299,7 @@ test_have_prereq() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		case "$satisfied_this_prereq,$negative_prereq" in
 | 
							case "$satisfied_this_prereq,$negative_prereq" in
 | 
				
			||||||
		t,|,t)
 | 
							t,|,t)
 | 
				
			||||||
			ok_prereq=$(($ok_prereq + 1))
 | 
								ok_prereq=$((ok_prereq + 1))
 | 
				
			||||||
			;;
 | 
								;;
 | 
				
			||||||
		*)
 | 
							*)
 | 
				
			||||||
			# Keep a list of missing prerequisites; restore
 | 
								# Keep a list of missing prerequisites; restore
 | 
				
			||||||
@@ -247,12 +320,12 @@ test_have_prereq() {
 | 
				
			|||||||
# the text_expect_* functions instead.
 | 
					# the text_expect_* functions instead.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test_ok_() {
 | 
					test_ok_() {
 | 
				
			||||||
	test_success=$(($test_success + 1))
 | 
						test_success=$((test_success + 1))
 | 
				
			||||||
	say_color "" "ok $test_count - $@"
 | 
						say_color "" "ok $test_count - $*"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test_failure_() {
 | 
					test_failure_() {
 | 
				
			||||||
	test_failure=$(($test_failure + 1))
 | 
						test_failure=$((test_failure + 1))
 | 
				
			||||||
	say_color error "not ok $test_count - $1"
 | 
						say_color error "not ok $test_count - $1"
 | 
				
			||||||
	shift
 | 
						shift
 | 
				
			||||||
	echo "$@" | sed -e 's/^/#	/'
 | 
						echo "$@" | sed -e 's/^/#	/'
 | 
				
			||||||
@@ -260,13 +333,13 @@ test_failure_() {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test_known_broken_ok_() {
 | 
					test_known_broken_ok_() {
 | 
				
			||||||
	test_fixed=$(($test_fixed + 1))
 | 
						test_fixed=$((test_fixed + 1))
 | 
				
			||||||
	say_color error "ok $test_count - $@ # TODO known breakage vanished"
 | 
						say_color error "ok $test_count - $* # TODO known breakage vanished"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test_known_broken_failure_() {
 | 
					test_known_broken_failure_() {
 | 
				
			||||||
	test_broken=$(($test_broken + 1))
 | 
						test_broken=$((test_broken + 1))
 | 
				
			||||||
	say_color warn "not ok $test_count - $@ # TODO known breakage"
 | 
						say_color warn "not ok $test_count - $* # TODO known breakage"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Public: Execute commands in debug mode.
 | 
					# Public: Execute commands in debug mode.
 | 
				
			||||||
@@ -287,10 +360,29 @@ test_debug() {
 | 
				
			|||||||
	test "$debug" = "" || eval "$1"
 | 
						test "$debug" = "" || eval "$1"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Public: Stop execution and start a shell.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# This is useful for debugging tests and only makes sense together with "-v".
 | 
				
			||||||
 | 
					# Be sure to remove all invocations of this command before submitting.
 | 
				
			||||||
 | 
					test_pause() {
 | 
				
			||||||
 | 
						if test "$verbose" = t; then
 | 
				
			||||||
 | 
							"$SHELL_PATH" <&6 >&3 2>&4
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							error >&5 "test_pause requires --verbose"
 | 
				
			||||||
 | 
						fi
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test_eval_() {
 | 
					test_eval_() {
 | 
				
			||||||
	# This is a separate function because some tests use
 | 
						# This is a separate function because some tests use
 | 
				
			||||||
	# "return" to end a test_expect_success block early.
 | 
						# "return" to end a test_expect_success block early.
 | 
				
			||||||
 | 
						case ",$test_prereq," in
 | 
				
			||||||
 | 
						*,INTERACTIVE,*)
 | 
				
			||||||
 | 
							eval "$*"
 | 
				
			||||||
 | 
							;;
 | 
				
			||||||
 | 
						*)
 | 
				
			||||||
		eval </dev/null >&3 2>&4 "$*"
 | 
							eval </dev/null >&3 2>&4 "$*"
 | 
				
			||||||
 | 
							;;
 | 
				
			||||||
 | 
						esac
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test_run_() {
 | 
					test_run_() {
 | 
				
			||||||
@@ -299,6 +391,13 @@ test_run_() {
 | 
				
			|||||||
	test_eval_ "$1"
 | 
						test_eval_ "$1"
 | 
				
			||||||
	eval_ret=$?
 | 
						eval_ret=$?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if test "$chain_lint" = "t"; then
 | 
				
			||||||
 | 
							test_eval_ "(exit 117) && $1"
 | 
				
			||||||
 | 
							if test "$?" != 117; then
 | 
				
			||||||
 | 
								error "bug in the test script: broken &&-chain: $1"
 | 
				
			||||||
 | 
							fi
 | 
				
			||||||
 | 
						fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if test -z "$immediate" || test $eval_ret = 0 || test -n "$expecting_failure"; then
 | 
						if test -z "$immediate" || test $eval_ret = 0 || test -n "$expecting_failure"; then
 | 
				
			||||||
		test_eval_ "$test_cleanup"
 | 
							test_eval_ "$test_cleanup"
 | 
				
			||||||
	fi
 | 
						fi
 | 
				
			||||||
@@ -309,7 +408,7 @@ test_run_() {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test_skip_() {
 | 
					test_skip_() {
 | 
				
			||||||
	test_count=$(($test_count + 1))
 | 
						test_count=$((test_count + 1))
 | 
				
			||||||
	to_skip=
 | 
						to_skip=
 | 
				
			||||||
	for skp in $SKIP_TESTS; do
 | 
						for skp in $SKIP_TESTS; do
 | 
				
			||||||
		case $this_test.$test_count in
 | 
							case $this_test.$test_count in
 | 
				
			||||||
@@ -328,7 +427,7 @@ test_skip_() {
 | 
				
			|||||||
			of_prereq=" of $test_prereq"
 | 
								of_prereq=" of $test_prereq"
 | 
				
			||||||
		fi
 | 
							fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		say_color skip >&3 "skipping test: $@"
 | 
							say_color skip >&3 "skipping test: $*"
 | 
				
			||||||
		say_color skip "ok $test_count # skip $1 (missing $missing_prereq${of_prereq})"
 | 
							say_color skip "ok $test_count # skip $1 (missing $missing_prereq${of_prereq})"
 | 
				
			||||||
		: true
 | 
							: true
 | 
				
			||||||
		;;
 | 
							;;
 | 
				
			||||||
@@ -426,6 +525,44 @@ test_expect_failure() {
 | 
				
			|||||||
	echo >&3 ""
 | 
						echo >&3 ""
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Public: Run test commands and expect anything from them. Used when a
 | 
				
			||||||
 | 
					# test is not stable or not finished for some reason.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# When the test passed, an "ok" message is printed, but the number of
 | 
				
			||||||
 | 
					# fixed tests is not incremented.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# When it failed, a "not ok ... # TODO known breakage" message is
 | 
				
			||||||
 | 
					# printed, and the number of tests still broken is incremented.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Failures from these tests won't cause --immediate to stop.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Usually takes two arguments:
 | 
				
			||||||
 | 
					# $1 - Test description
 | 
				
			||||||
 | 
					# $2 - Commands to be executed.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# With three arguments, the first will be taken to be a prerequisite:
 | 
				
			||||||
 | 
					# $1 - Comma-separated list of test prerequisites. The test will be skipped if
 | 
				
			||||||
 | 
					#      not all of the given prerequisites are set. To negate a prerequisite,
 | 
				
			||||||
 | 
					#      put a "!" in front of it.
 | 
				
			||||||
 | 
					# $2 - Test description
 | 
				
			||||||
 | 
					# $3 - Commands to be executed.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Returns nothing.
 | 
				
			||||||
 | 
					test_expect_unstable() {
 | 
				
			||||||
 | 
						test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq=
 | 
				
			||||||
 | 
						test "$#" = 2 || error "bug in the test script: not 2 or 3 parameters to test_expect_unstable"
 | 
				
			||||||
 | 
						export test_prereq
 | 
				
			||||||
 | 
						if ! test_skip_ "$@"; then
 | 
				
			||||||
 | 
							say >&3 "checking unstable test: $2"
 | 
				
			||||||
 | 
							if test_run_ "$2" unstable; then
 | 
				
			||||||
 | 
								test_ok_ "$1"
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								test_known_broken_failure_ "$1"
 | 
				
			||||||
 | 
							fi
 | 
				
			||||||
 | 
						fi
 | 
				
			||||||
 | 
						echo >&3 ""
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Public: Run command and ensure that it fails in a controlled way.
 | 
					# Public: Run command and ensure that it fails in a controlled way.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# Use it instead of "! <command>". For example, when <command> dies due to a
 | 
					# Use it instead of "! <command>". For example, when <command> dies due to a
 | 
				
			||||||
@@ -518,7 +655,7 @@ test_expect_code() {
 | 
				
			|||||||
	shift
 | 
						shift
 | 
				
			||||||
	"$@"
 | 
						"$@"
 | 
				
			||||||
	exit_code=$?
 | 
						exit_code=$?
 | 
				
			||||||
	if test $exit_code = $want_code; then
 | 
						if test "$exit_code" = "$want_code"; then
 | 
				
			||||||
		return 0
 | 
							return 0
 | 
				
			||||||
	fi
 | 
						fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -528,7 +665,7 @@ test_expect_code() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# Public: Compare two files to see if expected output matches actual output.
 | 
					# Public: Compare two files to see if expected output matches actual output.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# The TEST_CMP variable defines the command used for the comparision; it
 | 
					# The TEST_CMP variable defines the command used for the comparison; it
 | 
				
			||||||
# defaults to "diff -u". Only when the test script was started with --verbose,
 | 
					# defaults to "diff -u". Only when the test script was started with --verbose,
 | 
				
			||||||
# will the command's output, the diff, be printed to the standard output.
 | 
					# will the command's output, the diff, be printed to the standard output.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
@@ -551,6 +688,79 @@ test_cmp() {
 | 
				
			|||||||
	${TEST_CMP:-diff -u} "$@"
 | 
						${TEST_CMP:-diff -u} "$@"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Public: portably print a sequence of numbers.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# seq is not in POSIX and GNU seq might not be available everywhere,
 | 
				
			||||||
 | 
					# so it is nice to have a seq implementation, even a very simple one.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# $1 - Starting number.
 | 
				
			||||||
 | 
					# $2 - Ending number.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Examples
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#   test_expect_success 'foo works 10 times' '
 | 
				
			||||||
 | 
					#       for i in $(test_seq 1 10)
 | 
				
			||||||
 | 
					#       do
 | 
				
			||||||
 | 
					#           foo || return
 | 
				
			||||||
 | 
					#       done
 | 
				
			||||||
 | 
					#   '
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Returns 0 if all the specified numbers can be displayed.
 | 
				
			||||||
 | 
					test_seq() {
 | 
				
			||||||
 | 
						i="$1"
 | 
				
			||||||
 | 
						j="$2"
 | 
				
			||||||
 | 
						while test "$i" -le "$j"
 | 
				
			||||||
 | 
						do
 | 
				
			||||||
 | 
							echo "$i" || return
 | 
				
			||||||
 | 
							i=$(("$i" + 1))
 | 
				
			||||||
 | 
						done
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Public: Check if the file expected to be empty is indeed empty, and barfs
 | 
				
			||||||
 | 
					# otherwise.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# $1 - File to check for emptiness.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Returns 0 if file is empty, 1 otherwise.
 | 
				
			||||||
 | 
					test_must_be_empty() {
 | 
				
			||||||
 | 
						if test -s "$1"
 | 
				
			||||||
 | 
						then
 | 
				
			||||||
 | 
							echo "'$1' is not empty, it contains:"
 | 
				
			||||||
 | 
							cat "$1"
 | 
				
			||||||
 | 
							return 1
 | 
				
			||||||
 | 
						fi
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# debugging-friendly alternatives to "test [-f|-d|-e]"
 | 
				
			||||||
 | 
					# The commands test the existence or non-existence of $1. $2 can be
 | 
				
			||||||
 | 
					# given to provide a more precise diagnosis.
 | 
				
			||||||
 | 
					test_path_is_file () {
 | 
				
			||||||
 | 
						if ! test -f "$1"
 | 
				
			||||||
 | 
						then
 | 
				
			||||||
 | 
							echo "File $1 doesn't exist. $2"
 | 
				
			||||||
 | 
							false
 | 
				
			||||||
 | 
						fi
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_path_is_dir () {
 | 
				
			||||||
 | 
						if ! test -d "$1"
 | 
				
			||||||
 | 
						then
 | 
				
			||||||
 | 
							echo "Directory $1 doesn't exist. $2"
 | 
				
			||||||
 | 
							false
 | 
				
			||||||
 | 
						fi
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Check if the directory exists and is empty as expected, barf otherwise.
 | 
				
			||||||
 | 
					test_dir_is_empty () {
 | 
				
			||||||
 | 
						test_path_is_dir "$1" &&
 | 
				
			||||||
 | 
						if test -n "$(find "$1" -mindepth 1 -maxdepth 1)"
 | 
				
			||||||
 | 
						then
 | 
				
			||||||
 | 
							echo "Directory '$1' is not empty, it contains:"
 | 
				
			||||||
 | 
							ls -la "$1"
 | 
				
			||||||
 | 
							return 1
 | 
				
			||||||
 | 
						fi
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Public: Schedule cleanup commands to be run unconditionally at the end of a
 | 
					# Public: Schedule cleanup commands to be run unconditionally at the end of a
 | 
				
			||||||
# test.
 | 
					# test.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
@@ -576,6 +786,23 @@ test_when_finished() {
 | 
				
			|||||||
		} && (exit \"\$eval_ret\"); eval_ret=\$?; $test_cleanup"
 | 
							} && (exit \"\$eval_ret\"); eval_ret=\$?; $test_cleanup"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Public: Schedule cleanup commands to be run unconditionally when all tests
 | 
				
			||||||
 | 
					# have run.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# This can be used to clean up things like test databases. It is not needed to
 | 
				
			||||||
 | 
					# clean up temporary files, as test_done already does that.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Examples:
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#   cleanup mysql -e "DROP DATABASE mytest"
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Returns the exit code of the last cleanup command executed.
 | 
				
			||||||
 | 
					final_cleanup=
 | 
				
			||||||
 | 
					cleanup() {
 | 
				
			||||||
 | 
						final_cleanup="{ $*
 | 
				
			||||||
 | 
							} && (exit \"\$eval_ret\"); eval_ret=\$?; $final_cleanup"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Public: Summarize test results and exit with an appropriate error code.
 | 
					# Public: Summarize test results and exit with an appropriate error code.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# Must be called at the end of each test script.
 | 
					# Must be called at the end of each test script.
 | 
				
			||||||
@@ -600,9 +827,9 @@ test_done() {
 | 
				
			|||||||
	EXIT_OK=t
 | 
						EXIT_OK=t
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if test -z "$HARNESS_ACTIVE"; then
 | 
						if test -z "$HARNESS_ACTIVE"; then
 | 
				
			||||||
		test_results_dir="$SHARNESS_TEST_DIRECTORY/test-results"
 | 
							test_results_dir="$SHARNESS_TEST_OUTPUT_DIRECTORY/test-results"
 | 
				
			||||||
		mkdir -p "$test_results_dir"
 | 
							mkdir -p "$test_results_dir"
 | 
				
			||||||
		test_results_path="$test_results_dir/${SHARNESS_TEST_FILE%.$SHARNESS_TEST_EXTENSION}.$$.counts"
 | 
							test_results_path="$test_results_dir/$this_test.$$.counts"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		cat >>"$test_results_path" <<-EOF
 | 
							cat >>"$test_results_path" <<-EOF
 | 
				
			||||||
		total $test_count
 | 
							total $test_count
 | 
				
			||||||
@@ -621,7 +848,7 @@ test_done() {
 | 
				
			|||||||
		say_color warn "# still have $test_broken known breakage(s)"
 | 
							say_color warn "# still have $test_broken known breakage(s)"
 | 
				
			||||||
	fi
 | 
						fi
 | 
				
			||||||
	if test "$test_broken" != 0 || test "$test_fixed" != 0; then
 | 
						if test "$test_broken" != 0 || test "$test_fixed" != 0; then
 | 
				
			||||||
		test_remaining=$(( $test_count - $test_broken - $test_fixed ))
 | 
							test_remaining=$((test_count - test_broken - test_fixed))
 | 
				
			||||||
		msg="remaining $test_remaining test(s)"
 | 
							msg="remaining $test_remaining test(s)"
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		test_remaining=$test_count
 | 
							test_remaining=$test_count
 | 
				
			||||||
@@ -641,6 +868,8 @@ test_done() {
 | 
				
			|||||||
		fi
 | 
							fi
 | 
				
			||||||
		say "1..$test_count$skip_all"
 | 
							say "1..$test_count$skip_all"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							test_eval_ "$final_cleanup"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		test -d "$remove_trash" &&
 | 
							test -d "$remove_trash" &&
 | 
				
			||||||
		cd "$(dirname "$remove_trash")" &&
 | 
							cd "$(dirname "$remove_trash")" &&
 | 
				
			||||||
		rm -rf "$(basename "$remove_trash")"
 | 
							rm -rf "$(basename "$remove_trash")"
 | 
				
			||||||
@@ -656,14 +885,15 @@ test_done() {
 | 
				
			|||||||
	esac
 | 
						esac
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Public: Root directory containing tests. Tests can override this variable,
 | 
					# Public: Source directory of test code and sharness library.
 | 
				
			||||||
# e.g. for testing Sharness itself.
 | 
					# This directory may be different from the directory in which tests are
 | 
				
			||||||
: ${SHARNESS_TEST_DIRECTORY:=$(pwd)}
 | 
					# being run.
 | 
				
			||||||
export SHARNESS_TEST_DIRECTORY
 | 
					: "${SHARNESS_TEST_SRCDIR:=$(cd "$(dirname "$0")" && pwd)}"
 | 
				
			||||||
 | 
					export SHARNESS_TEST_SRCDIR
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Public: Build directory that will be added to PATH. By default, it is set to
 | 
					# Public: Build directory that will be added to PATH. By default, it is set to
 | 
				
			||||||
# the parent directory of SHARNESS_TEST_DIRECTORY.
 | 
					# the parent directory of SHARNESS_TEST_DIRECTORY.
 | 
				
			||||||
: ${SHARNESS_BUILD_DIRECTORY:="$SHARNESS_TEST_DIRECTORY/.."}
 | 
					: "${SHARNESS_BUILD_DIRECTORY:="$SHARNESS_TEST_DIRECTORY/.."}"
 | 
				
			||||||
PATH="$SHARNESS_BUILD_DIRECTORY:$PATH"
 | 
					PATH="$SHARNESS_BUILD_DIRECTORY:$PATH"
 | 
				
			||||||
export PATH SHARNESS_BUILD_DIRECTORY
 | 
					export PATH SHARNESS_BUILD_DIRECTORY
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -672,19 +902,43 @@ SHARNESS_TEST_FILE="$0"
 | 
				
			|||||||
export SHARNESS_TEST_FILE
 | 
					export SHARNESS_TEST_FILE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Prepare test area.
 | 
					# Prepare test area.
 | 
				
			||||||
test_dir="trash directory.$(basename "$SHARNESS_TEST_FILE" ".$SHARNESS_TEST_EXTENSION")"
 | 
					SHARNESS_TRASH_DIRECTORY="trash directory.$(basename "$SHARNESS_TEST_FILE" ".$SHARNESS_TEST_EXTENSION")"
 | 
				
			||||||
test -n "$root" && test_dir="$root/$test_dir"
 | 
					test -n "$root" && SHARNESS_TRASH_DIRECTORY="$root/$SHARNESS_TRASH_DIRECTORY"
 | 
				
			||||||
case "$test_dir" in
 | 
					case "$SHARNESS_TRASH_DIRECTORY" in
 | 
				
			||||||
/*) SHARNESS_TRASH_DIRECTORY="$test_dir" ;;
 | 
					/*) ;; # absolute path is good
 | 
				
			||||||
 *) SHARNESS_TRASH_DIRECTORY="$SHARNESS_TEST_DIRECTORY/$test_dir" ;;
 | 
					 *) SHARNESS_TRASH_DIRECTORY="$SHARNESS_TEST_OUTPUT_DIRECTORY/$SHARNESS_TRASH_DIRECTORY" ;;
 | 
				
			||||||
esac
 | 
					esac
 | 
				
			||||||
test "$debug" = "t" || remove_trash="$SHARNESS_TRASH_DIRECTORY"
 | 
					test "$debug" = "t" || remove_trash="$SHARNESS_TRASH_DIRECTORY"
 | 
				
			||||||
rm -rf "$test_dir" || {
 | 
					rm -rf "$SHARNESS_TRASH_DIRECTORY" || {
 | 
				
			||||||
	EXIT_OK=t
 | 
						EXIT_OK=t
 | 
				
			||||||
	echo >&5 "FATAL: Cannot prepare test area"
 | 
						echo >&5 "FATAL: Cannot prepare test area"
 | 
				
			||||||
	exit 1
 | 
						exit 1
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#  Load any extensions in $srcdir/sharness.d/*.sh
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					if test -d "${SHARNESS_TEST_SRCDIR}/sharness.d"
 | 
				
			||||||
 | 
					then
 | 
				
			||||||
 | 
						for file in "${SHARNESS_TEST_SRCDIR}"/sharness.d/*.sh
 | 
				
			||||||
 | 
						do
 | 
				
			||||||
 | 
							# Ensure glob was not an empty match:
 | 
				
			||||||
 | 
							test -e "${file}" || break
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if test -n "$debug"
 | 
				
			||||||
 | 
							then
 | 
				
			||||||
 | 
								echo >&5 "sharness: loading extensions from ${file}"
 | 
				
			||||||
 | 
							fi
 | 
				
			||||||
 | 
							. "${file}"
 | 
				
			||||||
 | 
							if test $? != 0
 | 
				
			||||||
 | 
							then
 | 
				
			||||||
 | 
								echo >&5 "sharness: Error loading ${file}. Aborting."
 | 
				
			||||||
 | 
								exit 1
 | 
				
			||||||
 | 
							fi
 | 
				
			||||||
 | 
						done
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Public: Empty trash directory, the test area, provided for each test. The HOME
 | 
					# Public: Empty trash directory, the test area, provided for each test. The HOME
 | 
				
			||||||
# variable is set to that directory too.
 | 
					# variable is set to that directory too.
 | 
				
			||||||
export SHARNESS_TRASH_DIRECTORY
 | 
					export SHARNESS_TRASH_DIRECTORY
 | 
				
			||||||
@@ -692,10 +946,10 @@ export SHARNESS_TRASH_DIRECTORY
 | 
				
			|||||||
HOME="$SHARNESS_TRASH_DIRECTORY"
 | 
					HOME="$SHARNESS_TRASH_DIRECTORY"
 | 
				
			||||||
export HOME
 | 
					export HOME
 | 
				
			||||||
 | 
					
 | 
				
			||||||
mkdir -p "$test_dir" || exit 1
 | 
					mkdir -p "$SHARNESS_TRASH_DIRECTORY" || exit 1
 | 
				
			||||||
# Use -P to resolve symlinks in our working directory so that the cwd
 | 
					# Use -P to resolve symlinks in our working directory so that the cwd
 | 
				
			||||||
# in subprocesses like git equals our $PWD (for pathname comparisons).
 | 
					# in subprocesses like git equals our $PWD (for pathname comparisons).
 | 
				
			||||||
cd -P "$test_dir" || exit 1
 | 
					cd -P "$SHARNESS_TRASH_DIRECTORY" || exit 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
this_test=${SHARNESS_TEST_FILE##*/}
 | 
					this_test=${SHARNESS_TEST_FILE##*/}
 | 
				
			||||||
this_test=${this_test%.$SHARNESS_TEST_EXTENSION}
 | 
					this_test=${this_test%.$SHARNESS_TEST_EXTENSION}
 | 
				
			||||||
@@ -708,4 +962,10 @@ for skp in $SKIP_TESTS; do
 | 
				
			|||||||
	esac
 | 
						esac
 | 
				
			||||||
done
 | 
					done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test -n "$TEST_LONG" && test_set_prereq EXPENSIVE
 | 
				
			||||||
 | 
					test -n "$TEST_INTERACTIVE" && test_set_prereq INTERACTIVE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Make sure this script ends with code 0
 | 
				
			||||||
 | 
					:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# vi: set ts=4 sw=4 noet :
 | 
					# vi: set ts=4 sw=4 noet :
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +1,55 @@
 | 
				
			|||||||
#!/bin/sh
 | 
					#!/bin/sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
. ./sharness.sh
 | 
					if [ -z "$SHARNESS" ] ; then
 | 
				
			||||||
 | 
						for d in \
 | 
				
			||||||
 | 
							"." \
 | 
				
			||||||
 | 
							"$HOME/share/sharness" \
 | 
				
			||||||
 | 
							"/usr/local/share/sharness" \
 | 
				
			||||||
 | 
							"/usr/share/sharness"
 | 
				
			||||||
 | 
						do
 | 
				
			||||||
 | 
							f="$d/sharness.sh"
 | 
				
			||||||
 | 
							if [ -f "$f" ] ; then
 | 
				
			||||||
 | 
								SHARNESS="$f"
 | 
				
			||||||
 | 
							fi
 | 
				
			||||||
 | 
						done
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					if [ -z "$SHARNESS" ] || [ ! -f "$SHARNESS" ] ; then
 | 
				
			||||||
 | 
						echo "sharness.sh not found" >&2
 | 
				
			||||||
 | 
						exit 1
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test_set_prereq PYTHON
 | 
					# Prevent sharness from adding the source directory to PATH
 | 
				
			||||||
 | 
					# since the scripts use unversioned python for their shebang
 | 
				
			||||||
 | 
					# but tests should run under the python with mercurial support
 | 
				
			||||||
 | 
					# so create an empty directory and strip it from PATH afterwards
 | 
				
			||||||
 | 
					SHARNESS_BUILD_DIRECTORY="$(mktemp -d)"
 | 
				
			||||||
 | 
					. "$SHARNESS"
 | 
				
			||||||
 | 
					export PATH="${PATH#*:}"
 | 
				
			||||||
 | 
					rmdir "$SHARNESS_BUILD_DIRECTORY"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [ -n "$PYTHON" ] && "$PYTHON" -c 'import mercurial' 2> /dev/null ; then
 | 
				
			||||||
 | 
						: Use chosen Python version
 | 
				
			||||||
 | 
					elif python3 -c 'import mercurial' 2> /dev/null ; then
 | 
				
			||||||
 | 
						PYTHON=python3
 | 
				
			||||||
 | 
					elif python2 -c 'import mercurial' 2> /dev/null ; then
 | 
				
			||||||
 | 
						PYTHON=python2
 | 
				
			||||||
 | 
					elif python -c 'import mercurial' 2> /dev/null ; then
 | 
				
			||||||
 | 
						PYTHON=python
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					if [ -n "$PYTHON" ] ; then
 | 
				
			||||||
 | 
						test_set_prereq PYTHON
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						# Change shebang on a copy of scripts to chosen Python version
 | 
				
			||||||
 | 
						TEST_BIN="$SHARNESS_TRASH_DIRECTORY/bin"
 | 
				
			||||||
 | 
						mkdir -p "$TEST_BIN"
 | 
				
			||||||
 | 
						for s in git-remote-hg git-hg-helper ; do
 | 
				
			||||||
 | 
							printf "%s\n" "#!/usr/bin/env $PYTHON" > "$TEST_BIN/$s"
 | 
				
			||||||
 | 
							tail -n +2 "$SHARNESS_TEST_DIRECTORY/../$s" >> "$TEST_BIN/$s"
 | 
				
			||||||
 | 
							chmod u+x "$TEST_BIN/$s"
 | 
				
			||||||
 | 
						done
 | 
				
			||||||
 | 
						export PATH="$TEST_BIN${PATH:+:$PATH}"
 | 
				
			||||||
 | 
						unset TEST_BIN
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GIT_AUTHOR_EMAIL=author@example.com
 | 
					GIT_AUTHOR_EMAIL=author@example.com
 | 
				
			||||||
GIT_AUTHOR_NAME='A U Thor'
 | 
					GIT_AUTHOR_NAME='A U Thor'
 | 
				
			||||||
@@ -10,3 +57,6 @@ GIT_COMMITTER_EMAIL=committer@example.com
 | 
				
			|||||||
GIT_COMMITTER_NAME='C O Mitter'
 | 
					GIT_COMMITTER_NAME='C O Mitter'
 | 
				
			||||||
export GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME
 | 
					export GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME
 | 
				
			||||||
export GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME
 | 
					export GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME
 | 
				
			||||||
 | 
					# maintain backwards compatible default
 | 
				
			||||||
 | 
					# (as used in remote helper)
 | 
				
			||||||
 | 
					git config --global init.defaultBranch master
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1
									
								
								tools/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tools/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					results.txt
 | 
				
			||||||
							
								
								
									
										303
									
								
								tools/check-versions
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										303
									
								
								tools/check-versions
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,303 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/env ruby
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Copyright (c) 2019 Felipe Contreras
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# This script runs the tests for all versions of the components:
 | 
				
			||||||
 | 
					#   hg, hggit and dulwich
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# You can run it without arguments, in which case it reads the file
 | 
				
			||||||
 | 
					# 'versions.txt' and executes all those checks.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Or you can pass the versions to check manually, like:
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#   ./check-versions hg:4.7 hggit:0.8.12 dulwich:0.19.7
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Or you can pass just the hg version, the other versions are fetched from
 | 
				
			||||||
 | 
					# 'versions.txt':
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#   ./check-versions hg:5.0
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require 'fileutils'
 | 
				
			||||||
 | 
					require 'tmpdir'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$tests = %w[main.t bidi.t hg-git.t]
 | 
				
			||||||
 | 
					$workdir = "#{Dir.home}/.cache/git-remote-hg"
 | 
				
			||||||
 | 
					$builddir = Dir.mktmpdir("git-remote-hg-build-")
 | 
				
			||||||
 | 
					$testoutdir = Dir.mktmpdir("git-remote-hg-tests-")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					at_exit {
 | 
				
			||||||
 | 
					  FileUtils.remove_entry($builddir)
 | 
				
			||||||
 | 
					  FileUtils.remove_entry($testoutdir)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QUIET, LOW, HIGH = (1..3).to_a
 | 
				
			||||||
 | 
					$verbosity = LOW
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Util {{{1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def section(text)
 | 
				
			||||||
 | 
					  puts [nil, text, '=' * text.size]
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def title(text)
 | 
				
			||||||
 | 
					  puts [nil, text, '-' * text.size] unless $verbosity < HIGH
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def run_cmd(cmd, fatal: true)
 | 
				
			||||||
 | 
					  puts cmd.join(' ') unless $verbosity < HIGH
 | 
				
			||||||
 | 
					  result = system(*cmd)
 | 
				
			||||||
 | 
					  unless result or not fatal
 | 
				
			||||||
 | 
					    STDERR.puts "Failed to run command '%s'" % cmd.join(' ')
 | 
				
			||||||
 | 
					    exit -1
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					  result
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def check_version(a, b)
 | 
				
			||||||
 | 
					  return true if a == '@'
 | 
				
			||||||
 | 
					  a = a.split('.').map(&:to_i)
 | 
				
			||||||
 | 
					  b = b.split('.').map(&:to_i)
 | 
				
			||||||
 | 
					  (a <=> b) >= 0
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Component {{{1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Component
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  attr_reader :id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def initialize(id, url, kind: nil, **args)
 | 
				
			||||||
 | 
					    @id = id
 | 
				
			||||||
 | 
					    @url = url
 | 
				
			||||||
 | 
					    @kind = kind || (url.start_with?('git') ? :git : :hg)
 | 
				
			||||||
 | 
					    @tool = @kind.to_s
 | 
				
			||||||
 | 
					    @checkout_fix = args[:checkout_fix]
 | 
				
			||||||
 | 
					    @version_format = args[:version_format]
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def dir
 | 
				
			||||||
 | 
					    "#{$workdir}/#{@id}"
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def get_version(version)
 | 
				
			||||||
 | 
					    return @kind == :hg ? 'tip' : '@' if version == '@'
 | 
				
			||||||
 | 
					    @version_format ? @version_format % version : version
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def clone
 | 
				
			||||||
 | 
					    run_cmd [@tool, 'clone', '-q', @url, dir]
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def checkout(version)
 | 
				
			||||||
 | 
					    Dir.chdir(dir) do
 | 
				
			||||||
 | 
					      case @kind
 | 
				
			||||||
 | 
					      when :hg
 | 
				
			||||||
 | 
					        cmd = %w[update --clean]
 | 
				
			||||||
 | 
					      when :git
 | 
				
			||||||
 | 
					        cmd = %w[reset --hard]
 | 
				
			||||||
 | 
					      else
 | 
				
			||||||
 | 
					        cmd = %w[checkout]
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					      run_cmd [@tool] + cmd + ['-q', get_version(version)]
 | 
				
			||||||
 | 
					      @checkout_fix.call(version) if @checkout_fix
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def build
 | 
				
			||||||
 | 
					    Dir.chdir(dir) do
 | 
				
			||||||
 | 
					      targets = %w[build_py build_ext].map { |e| [e, '--build-lib', "#{$builddir}/python"] }
 | 
				
			||||||
 | 
					      run_cmd %w[python setup.py --quiet] + targets.flatten
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Functions {{{1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def setup
 | 
				
			||||||
 | 
					  dirs = %w[bin python]
 | 
				
			||||||
 | 
					  FileUtils.mkdir_p(dirs.map { |e| "#{$builddir}/#{e}" })
 | 
				
			||||||
 | 
					  FileUtils.mkdir_p($workdir)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  $components.each do |id, component|
 | 
				
			||||||
 | 
					    next if File.exists?(component.dir)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if $verbosity < HIGH
 | 
				
			||||||
 | 
					      puts "Cloning #{component.id}"
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      title "Cloning #{component.id}"
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					    component.clone
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_env(paths: nil)
 | 
				
			||||||
 | 
					  old = ENV.to_h
 | 
				
			||||||
 | 
					  paths.each do |id, path|
 | 
				
			||||||
 | 
					    name = id.to_s
 | 
				
			||||||
 | 
					    ENV[name] = "#{path}:#{ENV[name]}"
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					  r = yield
 | 
				
			||||||
 | 
					  ENV.replace(old)
 | 
				
			||||||
 | 
					  return r
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def run_tests(tests)
 | 
				
			||||||
 | 
					  title "Running tests"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Dir.chdir("#{__dir__}/../test") do
 | 
				
			||||||
 | 
					    case $verbosity
 | 
				
			||||||
 | 
					    when QUIET
 | 
				
			||||||
 | 
					      tests_opt = tests.join(' ')
 | 
				
			||||||
 | 
					      cmd = "prove -q #{tests_opt} :: -i"
 | 
				
			||||||
 | 
					    when LOW
 | 
				
			||||||
 | 
					      tests_opt = "T='%s'" % tests.join(' ')
 | 
				
			||||||
 | 
					      cmd = "make -j1 #{tests_opt}"
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      tests_opt = "T='%s'" % tests.join(' ')
 | 
				
			||||||
 | 
					      cmd = "TEST_OPTS='-v -i' make -j1 #{tests_opt}"
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					    system(cmd)
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def versions_to_s(versions)
 | 
				
			||||||
 | 
					  versions.map { |k,v| "#{k}:#{v}" }.join(' ')
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def versions_from_args(args)
 | 
				
			||||||
 | 
					  args.map { |e| k, v = e.split(':'); [k.to_sym, v] }.to_h
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def versions_from_s(str)
 | 
				
			||||||
 | 
					  versions_from_args(str.split(' '))
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def check(versions)
 | 
				
			||||||
 | 
					  section versions_to_s(versions)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  versions.each do |id, version|
 | 
				
			||||||
 | 
					    component = $components[id]
 | 
				
			||||||
 | 
					    next unless component
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    title "Checking out #{component.id} #{version}"
 | 
				
			||||||
 | 
					    component.checkout(version)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    title "Building #{component.id}"
 | 
				
			||||||
 | 
					    component.build
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  paths = {
 | 
				
			||||||
 | 
					    PATH: "#{$builddir}/bin",
 | 
				
			||||||
 | 
					    PYTHONPATH: "#{$builddir}/python",
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  test_env(paths: paths) do
 | 
				
			||||||
 | 
					    ENV['SHARNESS_TEST_OUTPUT_DIRECTORY'] = $testoutdir
 | 
				
			||||||
 | 
					    run_tests($tests)
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Add components {{{1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$components = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def add_component(id, url, **args)
 | 
				
			||||||
 | 
					  $components[id] = Component.new(id, url, **args)
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					hg_checkout_fix = lambda do |version|
 | 
				
			||||||
 | 
					  FileUtils.cp('hg', "#{$builddir}/bin/")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return if check_version(version, '4.3')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if run_cmd %W[hg import -q --no-commit #{__dir__}/hg_setup_hack_2.4.patch], fatal: false
 | 
				
			||||||
 | 
					    File.write('.hg_force_version', "%s\n" % version)
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    File.write('mercurial/__version__.py', "version = \"%s\"\n" % version)
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					add_component(:hg, 'https://www.mercurial-scm.org/repo/hg', checkout_fix: hg_checkout_fix)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					hggit_checkout_fix = lambda do |version|
 | 
				
			||||||
 | 
					  return unless check_version(version, '0.8.0')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  run_cmd %W[hg import -q --no-commit #{__dir__}/hggit_rename_fix_0.8.0.patch], fatal: false
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					add_component(:hggit, 'https://bitbucket.org/durin42/hg-git', checkout_fix: hggit_checkout_fix)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					add_component(:dulwich, 'https://github.com/dulwich/dulwich.git', version_format: 'dulwich-%s', kind: :git)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def load_checks(file)
 | 
				
			||||||
 | 
					  file.each do |e|
 | 
				
			||||||
 | 
					    e.chomp!
 | 
				
			||||||
 | 
					    next if e.empty? or e.start_with?('#')
 | 
				
			||||||
 | 
					    content, comment = e.split(' # ')
 | 
				
			||||||
 | 
					    versions = versions_from_s(content)
 | 
				
			||||||
 | 
					    $checks << versions
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def store_results(file)
 | 
				
			||||||
 | 
					  $results.each do |versions, result|
 | 
				
			||||||
 | 
					    content = versions_to_s(versions)
 | 
				
			||||||
 | 
					    comment = result ? 'OK' : 'FAIL'
 | 
				
			||||||
 | 
					    file.puts '%s # %s' % [content, comment]
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Main {{{1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					setup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$checks = []
 | 
				
			||||||
 | 
					$results = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$versions = versions_from_args(ARGV)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					File.open("#{__dir__}/versions.txt") do |f|
 | 
				
			||||||
 | 
					  load_checks(f)
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if $versions.size == 1 and $versions.key?(:hg)
 | 
				
			||||||
 | 
					  # mode 1
 | 
				
			||||||
 | 
					  $verbosity = LOW
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if ['@', nil].include?($versions[:hg])
 | 
				
			||||||
 | 
					    versions = $checks.last
 | 
				
			||||||
 | 
					    versions[:hg] = $versions[:hg] if $versions[:hg]
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    versions = $checks.find { |e| e[:hg] == $versions[:hg] }
 | 
				
			||||||
 | 
					    exit 1 unless versions
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  exit check(versions) ? 0 : 1
 | 
				
			||||||
 | 
					elsif not $versions.empty?
 | 
				
			||||||
 | 
					  # mode 2
 | 
				
			||||||
 | 
					  $verbosity = HIGH
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  exit check(versions) ? 0 : 1
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					  # mode 3
 | 
				
			||||||
 | 
					  $verbosity = QUIET
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  at_exit do
 | 
				
			||||||
 | 
					    File.open("#{__dir__}/results.txt", 'w') do |f|
 | 
				
			||||||
 | 
					      store_results(f)
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  failures = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  $checks.each do |versions|
 | 
				
			||||||
 | 
					    result = check(versions)
 | 
				
			||||||
 | 
					    failures += 1 unless result
 | 
				
			||||||
 | 
					    $results << [versions, result]
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  exit 1 unless failures == 0
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
							
								
								
									
										15
									
								
								tools/hg_setup_hack_2.4.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								tools/hg_setup_hack_2.4.patch
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
				
			|||||||
 | 
					diff --git a/setup.py b/setup.py
 | 
				
			||||||
 | 
					--- a/setup.py
 | 
				
			||||||
 | 
					+++ b/setup.py
 | 
				
			||||||
 | 
					@@ -181,7 +181,10 @@
 | 
				
			||||||
 | 
					     # error 0xc0150004. See: http://bugs.python.org/issue3440
 | 
				
			||||||
 | 
					     env['SystemRoot'] = os.environ['SystemRoot']
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					-if os.path.isdir('.hg'):
 | 
				
			||||||
 | 
					+if os.path.exists('.hg_force_version'):
 | 
				
			||||||
 | 
					+    with open('.hg_force_version') as f:
 | 
				
			||||||
 | 
					+        version = f.read().rstrip('\n')
 | 
				
			||||||
 | 
					+elif os.path.isdir('.hg'):
 | 
				
			||||||
 | 
					     cmd = [sys.executable, 'hg', 'log', '-r', '.', '--template', '{tags}\n']
 | 
				
			||||||
 | 
					     numerictags = [t for t in runhg(cmd, env).split() if t[0].isdigit()]
 | 
				
			||||||
 | 
					     hgid = runhg([sys.executable, 'hg', 'id', '-i'], env).strip()
 | 
				
			||||||
							
								
								
									
										22
									
								
								tools/hggit_rename_fix_0.8.0.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								tools/hggit_rename_fix_0.8.0.patch
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					diff --git a/hggit/git_handler.py b/hggit/git_handler.py
 | 
				
			||||||
 | 
					--- a/hggit/git_handler.py
 | 
				
			||||||
 | 
					+++ b/hggit/git_handler.py
 | 
				
			||||||
 | 
					@@ -693,6 +693,8 @@
 | 
				
			||||||
 | 
					     def import_git_commit(self, commit):
 | 
				
			||||||
 | 
					         self.ui.debug(_("importing: %s\n") % commit.id)
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					+        extra_in_message = self.ui.configbool('git', 'debugextrainmessage', False)
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					         detect_renames = False
 | 
				
			||||||
 | 
					         (strip_message, hg_renames,
 | 
				
			||||||
 | 
					          hg_branch, extra) = git2hg.extract_hg_metadata(
 | 
				
			||||||
 | 
					@@ -703,7 +705,8 @@
 | 
				
			||||||
 | 
					             # renames detected from Git. This is because we export an extra
 | 
				
			||||||
 | 
					             # 'HG:rename-source' Git parameter when this isn't set, which will
 | 
				
			||||||
 | 
					             # break bidirectionality.
 | 
				
			||||||
 | 
					-            extra['hg-git-rename-source'] = 'git'
 | 
				
			||||||
 | 
					+            if not extra_in_message:
 | 
				
			||||||
 | 
					+                extra['hg-git-rename-source'] = 'git'
 | 
				
			||||||
 | 
					         else:
 | 
				
			||||||
 | 
					             renames = hg_renames
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
							
								
								
									
										33
									
								
								tools/versions.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								tools/versions.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
				
			|||||||
 | 
					# vi: ft=ruby
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					hg:2.4 hggit:0.4.0 dulwich:0.9.0 # 2013_02
 | 
				
			||||||
 | 
					hg:2.5 hggit:0.4.0 dulwich:0.9.0 # 2013_02
 | 
				
			||||||
 | 
					hg:2.6 hggit:0.4.0 dulwich:0.9.0 # 2013_02
 | 
				
			||||||
 | 
					hg:2.7 hggit:0.4.0 dulwich:0.9.0 # 2013_02
 | 
				
			||||||
 | 
					hg:2.8 hggit:0.4.0 dulwich:0.9.0 # 2013_02
 | 
				
			||||||
 | 
					hg:2.9 hggit:0.4.0 dulwich:0.9.0 # 2013_02
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					hg:3.0 hggit:0.7.0 dulwich:0.10.0 # 2014_11
 | 
				
			||||||
 | 
					hg:3.1 hggit:0.7.0 dulwich:0.10.0 # 2014_11
 | 
				
			||||||
 | 
					hg:3.2 hggit:0.7.0 dulwich:0.10.0 # 2014_11
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					hg:3.3 hggit:0.8.4 dulwich:0.13.0 # 2016_01
 | 
				
			||||||
 | 
					hg:3.4 hggit:0.8.4 dulwich:0.13.0 # 2016_01
 | 
				
			||||||
 | 
					hg:3.5 hggit:0.8.4 dulwich:0.13.0 # 2016_01
 | 
				
			||||||
 | 
					hg:3.6 hggit:0.8.4 dulwich:0.13.0 # 2016_01
 | 
				
			||||||
 | 
					hg:3.7 hggit:0.8.4 dulwich:0.13.0 # 2016_01
 | 
				
			||||||
 | 
					hg:3.8 hggit:0.8.4 dulwich:0.13.0 # 2016_01
 | 
				
			||||||
 | 
					hg:3.9 hggit:0.8.4 dulwich:0.13.0 # 2016_01
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					hg:4.0 hggit:0.8.10 dulwich:0.18.0 # 2017_11
 | 
				
			||||||
 | 
					hg:4.1 hggit:0.8.10 dulwich:0.18.0 # 2017_11
 | 
				
			||||||
 | 
					hg:4.2 hggit:0.8.10 dulwich:0.18.0 # 2017_11
 | 
				
			||||||
 | 
					hg:4.3 hggit:0.8.10 dulwich:0.18.0 # 2017_11
 | 
				
			||||||
 | 
					hg:4.4 hggit:0.8.10 dulwich:0.18.0 # 2017_11
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					hg:4.5 hggit:0.8.11 dulwich:0.18.0 # 2018_02
 | 
				
			||||||
 | 
					hg:4.6 hggit:0.8.12 dulwich:0.19.7 # 2018_10
 | 
				
			||||||
 | 
					hg:4.7 hggit:0.8.12 dulwich:0.19.7 # 2018_10
 | 
				
			||||||
 | 
					hg:4.8 hggit:@ dulwich:0.19.11
 | 
				
			||||||
 | 
					hg:4.9 hggit:@ dulwich:0.19.11
 | 
				
			||||||
 | 
					hg:5.0 hggit:@ dulwich:0.19.11
 | 
				
			||||||
		Reference in New Issue
	
	Block a user