]> arthur.barton.de Git - bup.git/commitdiff
Add author and committer arguments to new_commit()
authorRob Browning <rlb@defaultvalue.org>
Fri, 14 Feb 2014 18:22:41 +0000 (12:22 -0600)
committerRob Browning <rlb@defaultvalue.org>
Sat, 13 Feb 2016 20:21:23 +0000 (14:21 -0600)
Support "bup get" and "bup rm", which need to write commits with
differing author and committer information.

Signed-off-by: Rob Browning <rlb@defaultvalue.org>
Tested-by: Rob Browning <rlb@defaultvalue.org>
cmd/save-cmd.py
cmd/split-cmd.py
lib/bup/git.py
lib/bup/t/tgit.py

index 4fa6dcae1981532311953c0577386ab5e0a9901a..56351efd66cd84100b41bd969124a9ff6edaaacb 100755 (executable)
@@ -12,9 +12,10 @@ import os, sys, stat, time, math
 from bup import hashsplit, git, options, index, client, metadata, hlinkdb
 from bup.hashsplit import GIT_MODE_TREE, GIT_MODE_FILE, GIT_MODE_SYMLINK
 from bup.helpers import (add_error, grafted_path_components, handle_ctrl_c,
-                         istty2, log, parse_date_or_fatal, parse_num,
+                         hostname, istty2, log, parse_date_or_fatal, parse_num,
                          path_components, progress, qprogress, resolve_parent,
-                         saved_errors, stripped_path_components)
+                         saved_errors, stripped_path_components,
+                         userfullname, username)
 
 
 optspec = """
@@ -454,7 +455,9 @@ if opt.tree:
     print tree.encode('hex')
 if opt.commit or opt.name:
     msg = 'bup save\n\nGenerated by command:\n%r\n' % sys.argv
-    commit = w.new_commit(oldref, tree, date, msg)
+    userline = '%s <%s@%s>' % (userfullname(), username(), hostname())
+    commit = w.new_commit(tree, oldref, userline, date, None,
+                          userline, date, None, msg)
     if opt.commit:
         print commit.encode('hex')
 
index abf37371973744d4f1b7f433153d2e40655e2b18..e813dd7d2658b4420ab21f9b9a7f4f78a7b9fc06 100755 (executable)
@@ -8,8 +8,8 @@ exec "$bup_python" "$0" ${1+"$@"}
 import os, sys, time
 
 from bup import hashsplit, git, options, client
-from bup.helpers import (handle_ctrl_c, log, parse_num, qprogress, reprogress,
-                         saved_errors)
+from bup.helpers import (handle_ctrl_c, hostname, log, parse_num, qprogress,
+                         reprogress, saved_errors, userfullname, username)
 
 
 optspec = """
@@ -179,7 +179,9 @@ if opt.tree:
 if opt.commit or opt.name:
     msg = 'bup split\n\nGenerated by command:\n%r\n' % sys.argv
     ref = opt.name and ('refs/heads/%s' % opt.name) or None
-    commit = pack_writer.new_commit(oldref, tree, date, msg)
+    userline = '%s <%s@%s>' % (userfullname(), username(), hostname())
+    commit = pack_writer.new_commit(tree, oldref, userline, date, None,
+                                    userline, date, None, msg)
     if opt.commit:
         print commit.encode('hex')
 
index 458810bbfece732d0c374c093790e0391b92f6f1..73071fa49671aefe8cab6f3c9856980d65a7df87 100644 (file)
@@ -93,6 +93,19 @@ def get_commit_items(id, cp):
     return parse_commit(commit_content)
 
 
+def _local_git_date_str(epoch_sec):
+    return '%d %s' % (epoch_sec, utc_offset_str(epoch_sec))
+
+
+def _git_date_str(epoch_sec, tz_offset_sec):
+    offs =  tz_offset_sec // 60
+    return '%d %s%02d%02d' \
+        % (epoch_sec,
+           '+' if offs >= 0 else '-',
+           abs(offs) // 60,
+           abs(offs) % 60)
+
+
 def repo(sub = '', repo_dir=None):
     """Get the path to the git repository or one of its subdirectories."""
     global repodir
@@ -675,24 +688,29 @@ class PackWriter:
         content = tree_encode(shalist)
         return self.maybe_write('tree', content)
 
-    def _new_commit(self, tree, parent, author, adate, committer, cdate, msg):
+    def new_commit(self, tree, parent,
+                   author, adate_sec, adate_tz,
+                   committer, cdate_sec, cdate_tz,
+                   msg):
+        """Create a commit object in the pack.  The date_sec values must be
+        epoch-seconds, and if a tz is None, the local timezone is assumed."""
+        if adate_tz:
+            adate_str = _git_date_str(adate_sec, adate_tz)
+        else:
+            adate_str = _local_git_date_str(adate_sec)
+        if cdate_tz:
+            cdate_str = _git_date_str(cdate_sec, cdate_tz)
+        else:
+            cdate_str = _local_git_date_str(cdate_sec)
         l = []
         if tree: l.append('tree %s' % tree.encode('hex'))
         if parent: l.append('parent %s' % parent.encode('hex'))
-        if author: l.append('author %s %s' % (author, _git_date(adate)))
-        if committer: l.append('committer %s %s' % (committer, _git_date(cdate)))
+        if author: l.append('author %s %s' % (author, adate_str))
+        if committer: l.append('committer %s %s' % (committer, cdate_str))
         l.append('')
         l.append(msg)
         return self.maybe_write('commit', '\n'.join(l))
 
-    def new_commit(self, parent, tree, date, msg):
-        """Create a commit object in the pack."""
-        userline = '%s <%s@%s>' % (userfullname(), username(), hostname())
-        commit = self._new_commit(tree, parent,
-                                  userline, date, userline, date,
-                                  msg)
-        return commit
-
     def abort(self):
         """Remove the pack file from disk."""
         f = self.file
@@ -803,10 +821,6 @@ class PackWriter:
             idx_f.close()
 
 
-def _git_date(date):
-    return '%d %s' % (date, utc_offset_str(date))
-
-
 def _gitenv(repo_dir = None):
     if not repo_dir:
         repo_dir = repo()
index 8665e8011c1a69f9912e8bdea7e70ef35988c739..7487c4245b5b7d258dfc5420271fe2fdb684748d 100644 (file)
@@ -2,7 +2,7 @@ from subprocess import check_call
 import struct, os, subprocess, tempfile, time
 
 from bup import git
-from bup.helpers import log, mkdirp, readpipe
+from bup.helpers import localtime, log, mkdirp, readpipe
 
 from wvtest import *
 
@@ -289,6 +289,72 @@ def test_commit_parsing():
         subprocess.call(['rm', '-rf', tmpdir])
 
 
+@wvtest
+def test_new_commit():
+    initial_failures = wvfailure_count()
+    tmpdir = tempfile.mkdtemp(dir=bup_tmp, prefix='bup-tgit-')
+    os.environ['BUP_MAIN_EXE'] = bup_exe
+    os.environ['BUP_DIR'] = bupdir = tmpdir + "/bup"
+    git.init_repo(bupdir)
+    git.verbose = 1
+
+    w = git.PackWriter()
+    tree = os.urandom(20)
+    parent = os.urandom(20)
+    author_name = 'Author'
+    author_mail = 'author@somewhere'
+    adate_sec = 1439657836
+    cdate_sec = adate_sec + 1
+    committer_name = 'Committer'
+    committer_mail = 'committer@somewhere'
+    adate_tz_sec = cdate_tz_sec = None
+    commit = w.new_commit(tree, parent,
+                          '%s <%s>' % (author_name, author_mail),
+                          adate_sec, adate_tz_sec,
+                          '%s <%s>' % (committer_name, committer_mail),
+                          cdate_sec, cdate_tz_sec,
+                          'There is a small mailbox here')
+    adate_tz_sec = -60 * 60
+    cdate_tz_sec = 120 * 60
+    commit_off = w.new_commit(tree, parent,
+                              '%s <%s>' % (author_name, author_mail),
+                              adate_sec, adate_tz_sec,
+                              '%s <%s>' % (committer_name, committer_mail),
+                              cdate_sec, cdate_tz_sec,
+                              'There is a small mailbox here')
+    w.close()
+
+    commit_items = git.get_commit_items(commit.encode('hex'), git.cp())
+    local_author_offset = localtime(adate_sec).tm_gmtoff
+    local_committer_offset = localtime(cdate_sec).tm_gmtoff
+    WVPASSEQ(tree, commit_items.tree.decode('hex'))
+    WVPASSEQ(1, len(commit_items.parents))
+    WVPASSEQ(parent, commit_items.parents[0].decode('hex'))
+    WVPASSEQ(author_name, commit_items.author_name)
+    WVPASSEQ(author_mail, commit_items.author_mail)
+    WVPASSEQ(adate_sec, commit_items.author_sec)
+    WVPASSEQ(local_author_offset, commit_items.author_offset)
+    WVPASSEQ(committer_name, commit_items.committer_name)
+    WVPASSEQ(committer_mail, commit_items.committer_mail)
+    WVPASSEQ(cdate_sec, commit_items.committer_sec)
+    WVPASSEQ(local_committer_offset, commit_items.committer_offset)
+
+    commit_items = git.get_commit_items(commit_off.encode('hex'), git.cp())
+    WVPASSEQ(tree, commit_items.tree.decode('hex'))
+    WVPASSEQ(1, len(commit_items.parents))
+    WVPASSEQ(parent, commit_items.parents[0].decode('hex'))
+    WVPASSEQ(author_name, commit_items.author_name)
+    WVPASSEQ(author_mail, commit_items.author_mail)
+    WVPASSEQ(adate_sec, commit_items.author_sec)
+    WVPASSEQ(adate_tz_sec, commit_items.author_offset)
+    WVPASSEQ(committer_name, commit_items.committer_name)
+    WVPASSEQ(committer_mail, commit_items.committer_mail)
+    WVPASSEQ(cdate_sec, commit_items.committer_sec)
+    WVPASSEQ(cdate_tz_sec, commit_items.committer_offset)
+    if wvfailure_count() == initial_failures:
+        subprocess.call(['rm', '-rf', tmpdir])
+
+
 @wvtest
 def test_list_refs():
     initial_failures = wvfailure_count()
@@ -340,3 +406,8 @@ def test_list_refs():
     WVPASSEQ(frozenset(git.list_refs(limit_to_tags=True)), expected_tags)
     if wvfailure_count() == initial_failures:
         subprocess.call(['rm', '-rf', tmpdir])
+
+def test__git_date_str():
+    WVPASSEQ('0 +0000', git._git_date_str(0, 0))
+    WVPASSEQ('0 -0130', git._git_date_str(0, -90 * 60))
+    WVPASSEQ('0 +0130', git._git_date_str(0, 90 * 60))