summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xgit-bz141
-rw-r--r--git-bz.txt21
2 files changed, 101 insertions, 61 deletions
diff --git a/git-bz b/git-bz
index c45b7f3..7f9dcf6 100755
--- a/git-bz
+++ b/git-bz
@@ -67,7 +67,10 @@ from ConfigParser import RawConfigParser, NoOptionError
import httplib
from optparse import OptionParser
import os
-from pysqlite2 import dbapi2 as sqlite
+try:
+ from sqlite3 import dbapi2 as sqlite
+except ImportError:
+ from pysqlite2 import dbapi2 as sqlite
import re
from StringIO import StringIO
from subprocess import Popen, CalledProcessError, PIPE
@@ -135,8 +138,10 @@ def git_run(command, *args, **kwargs):
output, error = process.communicate(input)
if process.returncode != 0:
if not quiet and not interactive:
- print >>sys.stderr, error,
- print output,
+ # Using print here could result in Python adding a stray space
+ # before the next print
+ sys.stderr.write(error)
+ sys.stdout.write(output)
raise CalledProcessError(process.returncode, " ".join(to_run))
if interactive:
@@ -462,7 +467,7 @@ class BugHandle:
class CookieError(Exception):
pass
-def do_get_cookies_from_sqlite(host, cookies_sqlite, browser, query):
+def do_get_cookies_from_sqlite(host, cookies_sqlite, browser, query, chromium_time):
result = {}
# We use a timeout of 0 since we expect to hit the browser holding
# the lock often and we need to fall back to making a copy without a delay
@@ -475,6 +480,14 @@ def do_get_cookies_from_sqlite(host, cookies_sqlite, browser, query):
now = time.time()
for name,value,path,expiry in cursor.fetchall():
# Excessive caution: toss out values that need to be quoted in a cookie header
+ expiry = float(expiry)
+ if chromium_time:
+ # Time stored in microseconds since epoch
+ expiry /= 1000000.
+ # Old chromium versions used to use the Unix epoch, but newer versions
+ # use the Windows epoch of January 1, 1601. Convert the latter to Unix epoch
+ if expiry > 11644473600:
+ expiry -= 11644473600
if float(expiry) > now and not re.search(r'[()<>@,;:\\"/\[\]?={} \t]', value):
result[name] = value
@@ -495,13 +508,15 @@ def get_cookies_from_sqlite_with_copy(host, cookies_sqlite, browser, *args, **kw
finally:
os.remove(db_copy)
-def get_cookies_from_sqlite(host, cookies_sqlite, browser, query):
+def get_cookies_from_sqlite(host, cookies_sqlite, browser, query, chromium_time=False):
try:
- result = do_get_cookies_from_sqlite(host, cookies_sqlite, browser, query)
+ result = do_get_cookies_from_sqlite(host, cookies_sqlite, browser, query,
+ chromium_time=chromium_time)
except sqlite.OperationalError, e:
if "database is locked" in str(e):
# Try making a temporary copy
- result = get_cookies_from_sqlite_with_copy(host, cookies_sqlite, browser, query)
+ result = get_cookies_from_sqlite_with_copy(host, cookies_sqlite, browser, query,
+ chromium_time=chromium_time)
else:
raise
@@ -539,24 +554,43 @@ def get_bugzilla_cookies_ff3(host):
return get_cookies_from_sqlite_xulrunner(host, cookies_sqlite, "Firefox")
def get_bugzilla_cookies_epy(host):
- ff_dir = os.path.expanduser('~/.gnome2/epiphany/mozilla/epiphany')
- cookies_sqlite = os.path.join(ff_dir, "cookies.sqlite")
+ # epiphany-webkit migrated the cookie db to a different location, but the
+ # format is the same
+ profile_dir = os.path.expanduser('~/.gnome2/epiphany')
+ cookies_sqlite = os.path.join(profile_dir, "cookies.sqlite")
+ if not os.path.exists(cookies_sqlite):
+ # try the old location
+ cookies_sqlite = os.path.join(profile_dir, "mozilla/epiphany/cookies.sqlite")
+
if not os.path.exists(cookies_sqlite):
raise CookieError("%s doesn't exist" % cookies_sqlite)
return get_cookies_from_sqlite_xulrunner(host, cookies_sqlite, "Epiphany")
-def get_bugzilla_cookies_chromium(host):
- config_dir = os.path.expanduser('~/.config/chromium/Default')
+# Shared for Chromium and Google Chrome
+def get_bugzilla_cookies_chr(host, browser, config_dir):
+ config_dir = os.path.expanduser(config_dir)
cookies_sqlite = os.path.join(config_dir, "Cookies")
if not os.path.exists(cookies_sqlite):
raise CookieError("%s doesn't exist" % cookies_sqlite)
- return get_cookies_from_sqlite(host, cookies_sqlite, "Chromium",
- "select name,value,path,expires_utc from cookies where host_key = :host")
+ return get_cookies_from_sqlite(host, cookies_sqlite, browser,
+ "select name,value,path,expires_utc from cookies where host_key = :host",
+ chromium_time=True)
+
+def get_bugzilla_cookies_chromium(host):
+ return get_bugzilla_cookies_chr(host,
+ "Chromium",
+ '~/.config/chromium/Default')
+
+def get_bugzilla_cookies_google_chrome(host):
+ return get_bugzilla_cookies_chr(host,
+ "Google Chrome",
+ '~/.config/google-chrome/Default')
-browsers = { 'firefox3': get_bugzilla_cookies_ff3,
- 'epiphany': get_bugzilla_cookies_epy,
- 'chromium': get_bugzilla_cookies_chromium }
+browsers = { 'firefox3' : get_bugzilla_cookies_ff3,
+ 'epiphany' : get_bugzilla_cookies_epy,
+ 'chromium' : get_bugzilla_cookies_chromium,
+ 'google-chrome': get_bugzilla_cookies_google_chrome }
def browser_list():
return ", ".join(sorted(browsers.keys()))
@@ -737,9 +771,15 @@ def expand_abbreviation(abbrev, l):
raise ValueError("No unique abbreviation expansion")
def prompt(message):
- print message, "[yn] ",
- line = sys.stdin.readline().strip()
- return line == 'y' or line == 'Y'
+ while True:
+ # Using print here could result in Python adding a stray space
+ # before the next print
+ sys.stdout.write(message + " [yn] ")
+ line = sys.stdin.readline().strip()
+ if line == 'y' or line == 'Y':
+ return True
+ elif line == 'n' or line == 'N':
+ return False
def die(message):
print >>sys.stderr, message
@@ -1215,8 +1255,8 @@ def check_add_url(commits, bug_id=None, is_add_url=False):
return
try:
- git.diff(exit_code=True, _quiet=True)
- git.diff(exit_code=True, cached=True, _quiet=True)
+ git.diff(exit_code=True, ignore_submodules=True, _quiet=True)
+ git.diff(exit_code=True, ignore_submodules=True, cached=True, _quiet=True)
except CalledProcessError:
die("Cannot add bug reference to commit message(s); You must commit (or stash) all changes first")
@@ -1301,19 +1341,21 @@ def add_url_to_head_commit(commit, bug):
git.commit(file="-", amend=True, _input=input)
def add_url(bug, commits):
- # Avoid the rebase if nothing to do
- commits = [commit for commit in commits if commit_needs_url(commit, bug.id)]
- if len(commits) == 0: # Nothing to do
+ commit_map = {}
+ oldest_commit = None
+ for commit in commits:
+ commit_map[commit.id] = commit
+ if commit_needs_url(commit, bug.id):
+ oldest_commit = commit
+
+ if not oldest_commit:
return
# Check that the add-url method is valid before starting the rebase
validate_add_url_method(bug)
- oldest_commit = commits[-1]
-
- newer_commits = rev_list_commits(commits[0].id + "..HEAD")
-
- orig_head = newer_commits[0].id if newer_commits else commits[0].id
+ all_commits = rev_list_commits(oldest_commit.id + "^..HEAD")
+ orig_head = all_commits[0].id
try:
branch_name = git.symbolic_ref("HEAD", q=True)
@@ -1324,29 +1366,26 @@ def add_url(bug, commits):
print "Moving to starting point"
git.checkout(oldest_commit.id + "^", q=True)
- for commit in reversed(commits):
- if not commit_needs_url(commit, bug.id):
- print "Recommitting", commit.id[0:7], commit.subject, "(already has bug #)"
- git.cherry_pick(commit.id)
- # Find the new commit ID, though it doesn't matter much here
- commit.id = git.rev_parse("HEAD")
- continue
-
- print "Adding bug reference ", commit.id[0:7], commit.subject
- git.cherry_pick(commit.id)
+ for commit in reversed(all_commits):
+ # Map back to the original commit object so we can update it
+ if commit.id in commit_map:
+ commit = commit_map[commit.id]
- add_url_to_head_commit(commit, bug)
-
- # In this case, we need the new commit ID, so that when we later format the
- # patch, we format the patch with the added bug URL
- commit.id = git.rev_parse("HEAD")
+ if commit.id in commit_map and commit_needs_url(commit, bug.id):
+ print "Adding bug reference ", commit.id[0:7], commit.subject
+ git.cherry_pick(commit.id)
+ add_url_to_head_commit(commit, bug)
+ else:
+ if commit.id in commit_map:
+ print "Recommitting", commit.id[0:7], commit.subject, "(already has bug #)"
+ else:
+ print "Recommitting", commit.id[0:7], commit.subject
+ git.cherry_pick(commit.id)
- for commit in reversed(newer_commits):
- print "Recommitting", commit.id[0:7], commit.subject
- git.cherry_pick(commit.id)
- commit.id = git.rev_parse("HEAD")
+ # Get the commit ID; we update the commit with the new ID, so we in the case
+ # where we later format the patch, we format the patch with the added bug URL
+ new_head = commit.id = git.rev_parse("HEAD")
- new_head = newer_commits[0].id if newer_commits else commits[0].id
if branch_name is not None:
git.update_ref("-m", "bz add-url: adding references to %s" % bug.get_url(),
branch_name, new_head)
@@ -1747,7 +1786,7 @@ def edit_bug(bug, applied_commits=None, fix_commits=None):
return True
LOG_BUG_REFERENCE = re.compile(r"""
-(\b[Ss]ee\s+(?:\S+\s+){0,2})?
+(\b[Ss]ee\s+(?:[^\s:/]+\s+){0,2})?
(?:(https?://[^/]+/show_bug.cgi\?id=[^&\s]+)
|
[Bb]ug\s+\#?(\d+))
@@ -2044,7 +2083,7 @@ else:
global_options, args = parser.parse_args()
-if global_options.add_url is None:
+if hasattr(global_options, 'add_url') and global_options.add_url is None:
global_options.add_url = True
if len(args) < min_args or len(args) > max_args:
diff --git a/git-bz.txt b/git-bz.txt
index 7385419..648b4ec 100644
--- a/git-bz.txt
+++ b/git-bz.txt
@@ -52,26 +52,27 @@ you made locally to the bug report as a patch:
git bz attach 43215 HEAD
----------------------------------------
-This automatically rewrites the commit to add the URL of the bug to the commit for
-future reference. The reporter finds some problems in testing, so you come up
-with a new up with a new version of the change and modify your commit using
-'git command --amend'. To attach the new version, you run:
+This automatically rewrites the commit to add the URL of the bug to
+the commit message for future reference. The reporter finds some
+problems in testing, so you come up with a new version of the change
+and modify your commit using 'git command --amend'. To attach the new
+version, you run:
----------------------------------------
git bz attach -e HEAD
----------------------------------------
You don't have to specify the bug number this time since git-bz will
-find it it in the bug. The -e option (short for --edit) allows you to
-edit the comment for the bug to say what you've changed and pick
-patches to obsolete. Now everybody's happy with the change. To push
-your changes and close the bug, you run:
+find it in the commit message. The -e option (short for --edit)
+allows you to edit the comment for the bug to say what you've changed
+and pick patches to obsolete. Now everybody's happy with the
+change. To push your changes and close the bug, you run:
----------------------------------------
git bz push
----------------------------------------
-This does 'git bz push', adds a comment that the commits were pushed and
+This does 'git push', adds a comment that the commits were pushed and
marks the patches committed. The changes it is making to the bug will be
shown in your editor to give you a chance to confirm them and add
extra comments if desired.
@@ -266,7 +267,7 @@ Ways to refer to a bug:
<alias>:<id>:: bug # on the given bug tracker alias (see below)
-<url>:: An URL of the form http://<hostname>/show_bug.cgi?id-<id>
+<url>:: An URL of the form "http://<hostname>/show_bug.cgi?id-<id>"
[[add-url-method]]
ADD URL METHOD