git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[wishlist] git submodule update --reset-hard

From
Yaroslav Halchenko <yoh@onerussian.com>
Date
Dec 6, 2018, 17:35 UTC
Message-ID
<20181206173554.GH4633@hopa.kiewit.dartmouth.edu>
Dear Git Gurus,

I wondered what would be your take on my wishlist request to add --reset-hard option, which would be very similar to regular "update" which checks out necessary commit, but I want it to remain in the branch.

Rationale: In DataLad we heavily rely on submodules, and we have established
easy ways to do some manipulations across full hierarchies of them. E.g. a
single command could introduce a good number of commits across deep hierarchy
of submodules, e.g. while committing changes within deep submodule, while also
doing all necessary commits in the repositories leading to that submodule so
the entire tree of them stays in a "clean" state. The difficulty comes when
there is a need to just "forget" some changes.  The obvious way is to e.g. 
   git reset --hard PREVIOUS_STATE

in the top level repository. But that leaves all the submodules now in the undesired state. If I do

  git submodule update --recursive
I would end up in the detached HEADs within submodules.  

What I want is to retain current branch they are at (or may be possible "were in"? reflog records might have that information)

Example:

# Have to use datalad install since git clone --recurse-submodules # seems to not consider alternative locations for submodules' .git/ # with url being just a relative path, and where submodules aren't # all residing up under toplevel URL .git/

	$> datalad install -r http://datasets.datalad.org/labs/gobbini/.git
	[INFO   ] Cloning http://datasets.datalad.org/labs/gobbini/.git into '/tmp/gobbini' 
	install(ok): /tmp/gobbini (dataset)                                                                             
	[INFO   ] Installing <Dataset path=/tmp/gobbini> recursively 
	[INFO   ] Cloning http://datasets.datalad.org/labs/gobbini/famface/.git into '/tmp/gobbini/famface' 
	[INFO   ] Cloning http://datasets.datalad.org/labs/gobbini/famface/data/.git into '/tmp/gobbini/famface/data'   
	[INFO   ] access to dataset sibling "datasets.datalad.org" not auto-enabled, enable with:                       
	| 		datalad siblings -d "/tmp/gobbini/famface/data" enable -s datasets.datalad.org 
	[INFO   ] Cloning http://datasets.datalad.org/labs/gobbini/famface/data/scripts/mridefacer/.git [2 other candidates] into '/tmp/gobbini/famface/data/scripts/mridefacer' 
	action summary:                                                                                                 
	  install (ok: 4)

so I have a hierarchy in a good state and all checked out in master branch

	$> cd gobbini
	$> git submodule status --recursive       
	 b9071a6bc9f7665f7c75549c63d29f16d40e8af7 famface (heads/master)
	 e59ba76b42f219bdf14b6b547dd6d9cc0ed5227f famface/data (BIDS-v1.0.1-3-ge59ba76b)
	 5d8036c0aaeebb448a00df6296ddc9f799efdd1f famface/data/scripts/mridefacer (heads/master)
	$> git submodule foreach --recursive cat .git/HEAD                 
	Entering 'famface'
	ref: refs/heads/master
	Entering 'famface/data'
	ref: refs/heads/master
	Entering 'famface/data/scripts/mridefacer'
	ref: refs/heads/master
and if I do roll back
	$> git reset --hard HEAD^^^        
	HEAD is now at 9b4296d [DATALAD] aggregated meta data
	changes on filesystem:                                                                                          
	 famface | 2 +-
and default update --recursive
	$> git submodule update --recursive
	Submodule path 'famface': checked out '2569ab436501a832d35afbbe9cc20ffeb6077eb1'
	Submodule path 'famface/data': checked out 'f1e8c9b8b025c311424283b9711efc6bc906ba2b'
	Submodule path 'famface/data/scripts/mridefacer': checked out '49b0fe42696724c2a8492f999736056e51b77358'
I end up in detached HEADs
	$> git submodule status --recursive 
	 2569ab436501a832d35afbbe9cc20ffeb6077eb1 famface (2569ab4)
	 f1e8c9b8b025c311424283b9711efc6bc906ba2b famface/data (BIDS-v1.0.1)
	 49b0fe42696724c2a8492f999736056e51b77358 famface/data/scripts/mridefacer (49b0fe4)

I do see that there is a "custom command" way to do it via "submodule.<name>.update" config setting, but that is not easy to use for my case since all the `<name>` would be different to specify !git reset --hard for all of them via config option and I could not find any way to "glob" config (like submodule.*.update). But in effect that is probably what I need:

	# restarting from a clean state here
	$> git -c submodule.famface.update='!git reset --hard' submodule update --recursive    
	HEAD is now at 2569ab4 [DATALAD] aggregated meta data
	Submodule path 'famface': 'git reset --hard 2569ab436501a832d35afbbe9cc20ffeb6077eb1'
	Submodule path 'famface/data': checked out 'f1e8c9b8b025c311424283b9711efc6bc906ba2b'
	Submodule path 'famface/data/scripts/mridefacer': checked out '49b0fe42696724c2a8492f999736056e51b77358'
	$> git submodule status --recursive                                                
	 2569ab436501a832d35afbbe9cc20ffeb6077eb1 famface (heads/master)
	 f1e8c9b8b025c311424283b9711efc6bc906ba2b famface/data (BIDS-v1.0.1)
	 49b0fe42696724c2a8492f999736056e51b77358 famface/data/scripts/mridefacer (49b0fe4)

Corner cases I see which might make it trickier for a full blown solution (might be relevant to current state as well for other strategies):

-  If between those commits we got an additional submodule added (in
   immediate repository or within one of the subdatasets), ideally it
   should also be wiped out
-- 
Yaroslav O. Halchenko
Center for Open Neuroscience     http://centerforopenneuroscience.org
Dartmouth College, 419 Moore Hall, Hinman Box 6207, Hanover, NH 03755
Phone: +1 (603) 646-9834                       Fax: +1 (603) 646-1419
WWW:   http://www.linkedin.com/in/yarik        
Next: Stefan Beller
Message 1 of 18 in “[wishlist] git submodule update --reset-hard”
  1. Yaroslav HalchenkoDec 6, 2018
  2. Stefan BellerDec 6, 2018
  3. Yaroslav HalchenkoDec 6, 2018
  4. Stefan BellerDec 6, 2018
  5. Yaroslav HalchenkoDec 7, 2018
  6. Stefan BellerDec 7, 2018
  7. Yaroslav HalchenkoDec 8, 2018
  8. Yaroslav HalchenkoDec 8, 2018
  9. Stefan BellerDec 10, 2018
  10. Yaroslav HalchenkoDec 10, 2018
  11. 1/2 submodule: Add --reset-hard option for git submodule updateYaroslav Halchenko, Dec 11, 2018
  12. 2/2 RF+ENH(TST): compare the entire list of submodule status --recursive to stay intactYaroslav Halchenko, Dec 11, 2018
  13. Stefan BellerDec 12, 2018
  14. Yaroslav O HalchenkoDec 13, 2018
  15. Stefan BellerDec 13, 2018
  16. Yaroslav O HalchenkoDec 13, 2018
  17. Stefan BellerDec 13, 2018
  18. Yaroslav O HalchenkoDec 14, 2018

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.