Browse Source

Support empty incremental bundles

tags/v1.0
JustAnotherArchivist 1 year ago
parent
commit
2a9ff2ee15
1 changed files with 17 additions and 2 deletions
  1. +17
    -2
      codearchiver/modules/git.py

+ 17
- 2
codearchiver/modules/git.py View File

@@ -2,6 +2,7 @@ import codearchiver.core
import codearchiver.subprocess
import datetime
import functools
import hashlib
import logging
import os.path
import shutil
@@ -16,7 +17,7 @@ class GitIndex(codearchiver.core.Index):
codearchiver.core.IndexField(key = 'Based on bundle', required = False, repeatable = True),
codearchiver.core.IndexField(key = 'Ref', required = True, repeatable = True),
codearchiver.core.IndexField(key = 'Root commit', required = True, repeatable = True),
codearchiver.core.IndexField(key = 'Commit', required = True, repeatable = True),
codearchiver.core.IndexField(key = 'Commit', required = False, repeatable = True),
]


@@ -82,7 +83,21 @@ class Git(codearchiver.core.Module):
basedOnBundles[oldBundle] = True

_logger.info(f'Bundling into {bundle}')
codearchiver.subprocess.run_with_log(['git', 'bundle', 'create', '--progress', f'../{bundle}', '--stdin', '--reflog', '--all'], cwd = directory, input = ''.join(f'^{commit}\n' for commit in oldCommits).encode('ascii'))
status , _, stderr = codearchiver.subprocess.run_with_log(['git', 'bundle', 'create', '--progress', f'../{bundle}', '--stdin', '--reflog', '--all'], cwd = directory, input = ''.join(f'^{commit}\n' for commit in oldCommits).encode('ascii'), check = False)
if status == 128 and stderr == 'fatal: Refusing to create empty bundle.\n':
# Manually write an empty bundle instead
# Cf. Documentation/technical/bundle-format.txt and Documentation/technical/pack-format.txt in git's repository for details on the formats
_logger.info('Writing empty bundle directly instead')
with open(bundle, 'wb') as fp:
fp.write(b'# v2 git bundle\n') # bundle signature
fp.write(b'\n') # bundle end of prerequisites and refs
packdata = b'PACK' # pack signature
packdata += b'\0\0\0\x02' # pack version
packdata += b'\0\0\0\0' # pack number of objects
fp.write(packdata)
fp.write(hashlib.sha1(packdata).digest()) # pack checksum trailer
elif status != 0:
raise RuntimeError(f'git bundle creation returned with non-zero exit status {status}.')

_logger.info(f'Removing clone')
shutil.rmtree(directory)


Loading…
Cancel
Save