from datetime import datetime


def LatestDate(repo):
  date = 0
  for submodule in repo.submodules:
    subrepo = submodule.module()
    head = subrepo.head
    if head.is_detached:
      commitDate = head.commit.committed_date
    else:
      commitDate = head.ref.commit.committed_date

    if commitDate > date:
      date = commitDate

  return datetime.fromtimestamp(date)

def Branch(repo):
  head = repo.head
  if head.is_detached:
    return "DETACHED"
  return head.reference.name


def Update(repo, submodule, depth = None):
  if not submodule.module_exists():
    print('Cannot update {}, it has not been initialized yet. Run "init" first.'.format(submodule.name))
    return

  subrepo = submodule.module()
  remote = subrepo.remote('origin')
  head = subrepo.head
  if head.is_detached:
    print('Cannot update {}, it has a DETACHED HEAD. Resolve the detached head manually or run "checkout" to check out the correct branch.'.format(submodule.name))
  else:
    _SubmoduleUpdate(repo, submodule, depth = depth)

def UpdateAll(repo, depth = None):
  for submodule in repo.submodules:
    Update(repo, submodule, depth)

def _SubmoduleUpdate(repo, submodule, init = False, remote = True, recursive = True, depth = None):
  if not submodule.module_exists():
    init = True

  args = ['update', '--recursive']

  if init:
      args.append('--init')
  if remote:
      args.append('--remote')
  if recursive:
      args.append('--recursive')
  if depth:
    args.append('--depth')
    args.append(depth)

  if init:
    print('Initializing {}'.format(submodule.name))
  else:
    subrepo = submodule.module()
    remote = subrepo.remote('origin')
    head = subrepo.head
    print('Updating {} from {}/{}'.format(submodule.name, remote.name, head.reference.name))

  repo.git.submodule(args, '--', submodule.name)


def Checkout(submodule):
  branch = submodule.branch
  print('Switching {} to {}'.format(submodule.name, branch.name))
  branch.checkout()

  subrepo = submodule.module()
  for submodule in subrepo.submodules:
    Checkout(submodule)

def CheckoutAll(repo):
  for submodule in repo.submodules:
    Checkout(submodule)


def Clean(submodule):
  subrepo = submodule.module()
  print('Cleaning {}'.format(submodule.name))
  subrepo.git.clean('-fd')

def CleanAll(repo):
  for submodule in repo.submodules:
    Clean(submodule)


def Reset(submodule, toRemote):
  subrepo = submodule.module()
  if toRemote:
    head = subrepo.head
    if head.is_detached:
      print('Cannot reset, {} has a DETACHED HEAD.'.format(submodule.name))
      return
    remote = subrepo.remote('origin')
    branchName = '{}/{}'.format(remote.name, head.reference.name)
    print('Resetting {} to {}'.format(submodule.name, branchName))
    subrepo.git.reset('--hard', branchName)
  else:
    print('Resetting {}'.format(submodule.name))
    subrepo.git.reset('--hard')

def ResetAll(repo, toRemote):
  for submodule in repo.submodules:
    Reset(submodule, toRemote)


def Merge(submodule, branchName):
  subrepo = submodule.module()
  head = subrepo.head
  if head.is_detached:
    print('Cannot merge, {} has a DETACHED HEAD.'.format(submodule.name))
    return
  branch = subrepo.heads[branchName]
  if branch == None:
    print('Cannot merge, branch {} does not exist'.format(branchName))
    return
  print('Merging branch {} into {} in {}'.format(branch, head.reference.name, submodule.name))
  subrepo.index.merge_tree(branch)

def MergeAll(repo, branchName):
  for submodule in repo.submodules:
    Merge(submodule, branchName)


def Tag(submodule, tagName, tagDescription):
  print('Creating tag {} in {}'.format(tagName, submodule.name))
  subrepo = submodule.module()
  subrepo.create_tag(path = tagName, message = tagDescription)

def TagAll(repo, tagName, tagDescription):
  for submodule in repo.submodules:
    Tag(submodule, tagName, tagDescription)


def Push(submodule, **kwargs):
  print('Pushing {}'.format(submodule.name))
  subrepo = submodule.module()
  remote = subrepo.remote('origin')
  remote.push(**kwargs)

def PushAll(repo, **kwargs):
  for submodule in repo.submodules:
    Push(submodule, **kwargs)


def Track(submodule):
  subrepo = submodule.module()
  head = subrepo.head
  remote = subrepo.remote('origin')
  localBranchName = head.reference.name
  remoteBranchName = '{}/{}'.format(remote.name, localBranchName)
  print('Setting tracking branch for {} to {}'.format(localBranchName, remoteBranchName))
  subrepo.git.branch('-u', remoteBranchName, localBranchName)

def TrackAll(repo):
  for submodule in repo.submodules:
    Track(submodule)


def InitAll(repo, depth = None):
  for submodule in repo.submodules:
    _SubmoduleUpdate(repo, submodule, init = True, remote = False, recursive = True, depth = depth)

@@ -517,659 +517,8 @@
 ule,
- depth = None):%0A  if not submodule.module_exists():%0A    print('Cannot update %7B%7D, it has not been initialized yet. Run %22init%22 first.'.format(submodule.name))%0A    return%0A%0A  subrepo = submodule.module()%0A  remote = subrepo.remote('origin')%0A  head = subrepo.head%0A  if head.is_detached:%0A    print('Cannot update %7B%7D, it has a DETACHED HEAD. Resolve the detached head manually or run %22checkout%22 to check out the correct branch.'.format(submodule.name))%0A  else:%0A    _SubmoduleUpdate(repo, submodule, depth = depth)%0A%0Adef UpdateAll(repo, depth = None):%0A  for submodule in repo.submodules:%0A    Update(repo, submodule, depth)%0A%0Adef _SubmoduleUpdate(repo, submodule,
  ini
@@ -1021,24 +1021,111 @@
 ubrepo.head%0A
+    if head.is_detached:%0A      print('Updating %7B%7D'.format(submodule.name))%0A    else:%0A  
     print('U
@@ -1252,24 +1252,139 @@
 dule.name)%0A%0A
+def UpdateAll(repo, depth = None):%0A  for submodule in repo.submodules:%0A    Update(repo, submodule, depth = depth)%0A%0A
 %0Adef Checkou
@@ -4208,18 +4208,8 @@
     
-_Submodule
 Upda

Simplify submodule update