[pacman-dev] [PATCH 1/2] Enabled new interactive prompt and updated some tests.
From: Bryan Ischo <bryan@ischo.com> Enabled a new prompt to ask the user if they'd like to remove unresolvable packages from the transaction rather than failing it. Many pactest tests that used to fail not return success codes, because pacman now issues a prompt allowing the user to cancel rather than failing many transactions, and the pactest scripts always choose to cancel with no error rather than failing. The only net effect is that the return status of pacman is now 0 in cases where it used to be nonzero. Signed-off-by: Bryan Ischo <bryan@ischo.com> --- lib/libalpm/alpm.h | 3 ++- lib/libalpm/deps.c | 6 +++--- lib/libalpm/sync.c | 23 ++++++++++++++++++----- pactest/tests/provision020.py | 2 +- pactest/tests/provision022.py | 2 +- pactest/tests/sync1008.py | 2 +- pactest/tests/sync300.py | 2 +- src/pacman/callback.c | 16 ++++++++++++++++ 8 files changed, 43 insertions(+), 13 deletions(-) diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index 7b7ca4e..3836d60 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -371,7 +371,8 @@ typedef enum _pmtransconv_t { PM_TRANS_CONV_REPLACE_PKG = 0x02, PM_TRANS_CONV_CONFLICT_PKG = 0x04, PM_TRANS_CONV_CORRUPTED_PKG = 0x08, - PM_TRANS_CONV_LOCAL_NEWER = 0x10 + PM_TRANS_CONV_LOCAL_NEWER = 0x10, + PM_TRANS_CONV_REMOVE_PKGS = 0x20, } pmtransconv_t; /* Transaction Progress */ diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c index 41d2a83..ebcd18d 100644 --- a/lib/libalpm/deps.c +++ b/lib/libalpm/deps.c @@ -531,8 +531,8 @@ pmpkg_t *_alpm_resolvedep(pmdepend_t *dep, alpm_list_t *dbs, alpm_list_t *exclud !_alpm_pkg_find(excluding, pkg->name)) { if(_alpm_pkg_should_ignore(pkg)) { int install; - QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, pkg, - tpkg, NULL, &install); + QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, + pkg, tpkg, NULL, &install); if(!install) { continue; } @@ -609,7 +609,7 @@ int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *pkg, if(!spkg) { pm_errno = PM_ERR_UNSATISFIED_DEPS; char *missdepstring = alpm_dep_compute_string(missdep); - _alpm_log(PM_LOG_ERROR, _("cannot resolve \"%s\", a dependency of \"%s\"\n"), + _alpm_log(PM_LOG_WARNING, _("cannot resolve \"%s\", a dependency of \"%s\"\n"), missdepstring, tpkg->name); free(missdepstring); if(data) { diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c index 5e5ca92..ea903f4 100644 --- a/lib/libalpm/sync.c +++ b/lib/libalpm/sync.c @@ -442,12 +442,25 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync dependencies not already on the list */ } - /* If there were unresolvable top-level packages, fail the - transaction. */ + /* If there were unresolvable top-level packages, prompt the user to + see if they'd like to ignore them rather than failing the sync */ if(unresolvable != NULL) { - /* pm_errno is set by resolvedeps */ - ret = -1; - goto cleanup; + int remove_unresolvable = 0; + QUESTION(handle->trans, PM_TRANS_CONV_REMOVE_PKGS, unresolvable, NULL, NULL, &remove_unresolvable); + if (remove_unresolvable) { + /* User wants to remove the unresolvable packages from the + transaction, so simply drop the unresolvable list. The + packages will be removed from the actual transaction when + the transaction packages are replaced with a + dependency-reordered list below */ + alpm_list_free(unresolvable); + unresolvable = NULL; + } + else { + /* pm_errno is set by resolvedeps */ + ret = -1; + goto cleanup; + } } /* Add all packages which were "pulled" (i.e. weren't already in the diff --git a/pactest/tests/provision020.py b/pactest/tests/provision020.py index 7cb0a01..c9c0ac3 100644 --- a/pactest/tests/provision020.py +++ b/pactest/tests/provision020.py @@ -10,6 +10,6 @@ self.args = "-S %s" % p.name -self.addrule("PACMAN_RETCODE=1") +self.addrule("PACMAN_RETCODE=0") self.addrule("!PKG_EXIST=pkg1") self.addrule("PKG_EXIST=pkg2") diff --git a/pactest/tests/provision022.py b/pactest/tests/provision022.py index 4883d42..190a8b6 100644 --- a/pactest/tests/provision022.py +++ b/pactest/tests/provision022.py @@ -10,6 +10,6 @@ self.args = "-S %s" % p.name -self.addrule("PACMAN_RETCODE=1") +self.addrule("PACMAN_RETCODE=0") self.addrule("!PKG_EXIST=pkg1") self.addrule("PKG_EXIST=pkg2") diff --git a/pactest/tests/sync1008.py b/pactest/tests/sync1008.py index a606459..90c61df 100644 --- a/pactest/tests/sync1008.py +++ b/pactest/tests/sync1008.py @@ -14,6 +14,6 @@ self.args = "-S pkg" -self.addrule("PACMAN_RETCODE=1") +self.addrule("PACMAN_RETCODE=0") self.addrule("!PKG_EXIST=pkg") self.addrule("!PKG_EXIST=cpkg") diff --git a/pactest/tests/sync300.py b/pactest/tests/sync300.py index 31b520a..36d6758 100644 --- a/pactest/tests/sync300.py +++ b/pactest/tests/sync300.py @@ -9,6 +9,6 @@ self.args = "-S %s" % sp1.name -self.addrule("PACMAN_RETCODE=1") +self.addrule("PACMAN_RETCODE=0") self.addrule("!PKG_EXIST=pkg1") self.addrule("!PKG_EXIST=pkg2") diff --git a/src/pacman/callback.c b/src/pacman/callback.c index 6e7930c..d6b5b01 100644 --- a/src/pacman/callback.c +++ b/src/pacman/callback.c @@ -270,6 +270,22 @@ void cb_trans_conv(pmtransconv_t event, void *data1, void *data2, (char *)data2, (char *)data2); break; + case PM_TRANS_CONV_REMOVE_PKGS: + { + alpm_list_t *unresolved = (alpm_list_t *) data1; + alpm_list_t *namelist = NULL, *i; + for (i = unresolved; i; i = i->next) { + namelist = alpm_list_add(namelist, + (char *) alpm_pkg_get_name(i->data)); + } + printf(":: the following package(s) cannot be upgraded due to " + "unresolvable dependencies:\n"); + list_display(" ", namelist); + *response = yesno(_("\nDo you want to skip the above " + "package(s) for this upgrade?")); + alpm_list_free(namelist); + } + break; case PM_TRANS_CONV_LOCAL_NEWER: if(!config->op_s_downloadonly) { *response = yesno(_(":: %s-%s: local version is newer. Upgrade anyway?"), -- 1.6.1
From: Bryan Ischo <bryan@ischo.com> Don't prompt the user for unignore of IgnorePkg/IgnoreGroup packages, except for packages explicitly listed for sync by the user. This eliminates many unnecessary prompts when IgnorePkg/IgnoreGroup is used. Signed-off-by: Bryan Ischo <bryan@ischo.com> --- lib/libalpm/deps.c | 34 +++++++++++++++++++++++-------- lib/libalpm/deps.h | 2 +- lib/libalpm/sync.c | 4 +- pactest/tests/ignore001.py | 17 ++++++++++++++++ pactest/tests/ignore002.py | 35 +++++++++++++++++++++++++++++++++ pactest/tests/ignore003.py | 35 +++++++++++++++++++++++++++++++++ pactest/tests/ignore004.py | 46 ++++++++++++++++++++++++++++++++++++++++++++ pactest/tests/ignore005.py | 46 ++++++++++++++++++++++++++++++++++++++++++++ src/pacman/callback.c | 11 +-------- 9 files changed, 209 insertions(+), 21 deletions(-) create mode 100644 pactest/tests/ignore001.py create mode 100644 pactest/tests/ignore002.py create mode 100644 pactest/tests/ignore003.py create mode 100644 pactest/tests/ignore004.py create mode 100644 pactest/tests/ignore005.py diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c index ebcd18d..694e5be 100644 --- a/lib/libalpm/deps.c +++ b/lib/libalpm/deps.c @@ -504,8 +504,20 @@ void _alpm_recursedeps(pmdb_t *db, alpm_list_t *targs, int include_explicit) } } -/* helper function for resolvedeps: search for dep satisfier in dbs */ -pmpkg_t *_alpm_resolvedep(pmdepend_t *dep, alpm_list_t *dbs, alpm_list_t *excluding, pmpkg_t *tpkg) +/** + * helper function for resolvedeps: search for dep satisfier in dbs + * + * @param dep is the dependency to search for + * @param dbs are the databases to search + * @param excluding are the packages to exclude from the search + * @param prompt if true, will cause an unresolvable dependency to issue an + * interactive prompt asking whether the package should be removed from + * the transaction or the transaction aborted; if false, simply returns + * an error code without prompting + * @return the resolved package + **/ +pmpkg_t *_alpm_resolvedep(pmdepend_t *dep, alpm_list_t *dbs, + alpm_list_t *excluding, int prompt) { alpm_list_t *i, *j; /* 1. literals */ @@ -513,9 +525,11 @@ pmpkg_t *_alpm_resolvedep(pmdepend_t *dep, alpm_list_t *dbs, alpm_list_t *exclud pmpkg_t *pkg = _alpm_db_get_pkgfromcache(i->data, dep->name); if(pkg && alpm_depcmp(pkg, dep) && !_alpm_pkg_find(excluding, pkg->name)) { if(_alpm_pkg_should_ignore(pkg)) { - int install; - QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, pkg, - tpkg, NULL, &install); + int install = 0; + if (prompt) { + QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, pkg, + NULL, NULL, &install); + } if(!install) { continue; } @@ -530,9 +544,11 @@ pmpkg_t *_alpm_resolvedep(pmdepend_t *dep, alpm_list_t *dbs, alpm_list_t *exclud if(alpm_depcmp(pkg, dep) && strcmp(pkg->name, dep->name) && !_alpm_pkg_find(excluding, pkg->name)) { if(_alpm_pkg_should_ignore(pkg)) { - int install; - QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, - pkg, tpkg, NULL, &install); + int install = 0; + if (prompt) { + QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, + pkg, NULL, NULL, &install); + } if(!install) { continue; } @@ -605,7 +621,7 @@ int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *pkg, continue; } /* find a satisfier package in the given repositories */ - pmpkg_t *spkg = _alpm_resolvedep(missdep, dbs_sync, *packages, tpkg); + pmpkg_t *spkg = _alpm_resolvedep(missdep, dbs_sync, *packages, 0); if(!spkg) { pm_errno = PM_ERR_UNSATISFIED_DEPS; char *missdepstring = alpm_dep_compute_string(missdep); diff --git a/lib/libalpm/deps.h b/lib/libalpm/deps.h index 0727095..eb1400b 100644 --- a/lib/libalpm/deps.h +++ b/lib/libalpm/deps.h @@ -47,7 +47,7 @@ pmdepmissing_t *_alpm_depmiss_new(const char *target, pmdepend_t *dep, void _alpm_depmiss_free(pmdepmissing_t *miss); alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, int reverse); void _alpm_recursedeps(pmdb_t *db, alpm_list_t *targs, int include_explicit); -pmpkg_t *_alpm_resolvedep(pmdepend_t *dep, alpm_list_t *dbs, alpm_list_t *excluding, pmpkg_t *tpkg); +pmpkg_t *_alpm_resolvedep(pmdepend_t *dep, alpm_list_t *dbs, alpm_list_t *excluding, int prompt); int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *pkg, alpm_list_t **packages, alpm_list_t *remove, alpm_list_t **data); int _alpm_dep_edge(pmpkg_t *pkg1, pmpkg_t *pkg2); diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c index ea903f4..6e7c709 100644 --- a/lib/libalpm/sync.c +++ b/lib/libalpm/sync.c @@ -285,12 +285,12 @@ int _alpm_sync_addtarget(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sy RET_ERR(PM_ERR_PKG_REPO_NOT_FOUND, -1); } dep = _alpm_splitdep(targ); - spkg = _alpm_resolvedep(dep, dbs, NULL, NULL); + spkg = _alpm_resolvedep(dep, dbs, NULL, 1); _alpm_dep_free(dep); alpm_list_free(dbs); } else { dep = _alpm_splitdep(targline); - spkg = _alpm_resolvedep(dep, dbs_sync, NULL, NULL); + spkg = _alpm_resolvedep(dep, dbs_sync, NULL, 1); _alpm_dep_free(dep); } FREE(targline); diff --git a/pactest/tests/ignore001.py b/pactest/tests/ignore001.py new file mode 100644 index 0000000..92081fb --- /dev/null +++ b/pactest/tests/ignore001.py @@ -0,0 +1,17 @@ +self.description = "Sync with irrelevant ignored packages" + +package1 = pmpkg("package1") +self.addpkg2db("local", package1) + +package2 = pmpkg("package2") +self.addpkg2db("local", package2) + +package2up = pmpkg("package2", "2.0-1") +self.addpkg2db("sync", package2up) + +self.option["IgnorePkg"] = ["irrelevent"] +self.args = "-Su" + +self.addrule("PACMAN_RETCODE=0") +self.addrule("PKG_VERSION=package1|1.0-1") +self.addrule("PKG_VERSION=package2|2.0-1") diff --git a/pactest/tests/ignore002.py b/pactest/tests/ignore002.py new file mode 100644 index 0000000..b2c5593 --- /dev/null +++ b/pactest/tests/ignore002.py @@ -0,0 +1,35 @@ +self.description = "Sync with relevant ignored packages" + +package1 = pmpkg("package1") +self.addpkg2db("local", package1) + +package2 = pmpkg("package2") +self.addpkg2db("local", package2) + +package3 = pmpkg("package3") +package3.depends = ["package2=1.0-1"] +self.addpkg2db("local", package3) + +package4 = pmpkg("package4") +package4.depends = ["package3=1.0-1"] +self.addpkg2db("local", package4) + +package2up = pmpkg("package2", "2.0-1") +self.addpkg2db("sync", package2up) + +package3up = pmpkg("package3", "2.0-1") +package3up.depends = ["package2=2.0-1"] +self.addpkg2db("sync", package3up) + +package4up = pmpkg("package4", "2.0-1") +package4up.depends = ["package3=2.0-1"] +self.addpkg2db("sync", package4up) + +self.option["IgnorePkg"] = ["package2"] +self.args = "-Su" + +self.addrule("PACMAN_RETCODE=0") +self.addrule("PKG_VERSION=package1|1.0-1") +self.addrule("PKG_VERSION=package2|1.0-1") +self.addrule("PKG_VERSION=package3|1.0-1") +self.addrule("PKG_VERSION=package4|1.0-1") diff --git a/pactest/tests/ignore003.py b/pactest/tests/ignore003.py new file mode 100644 index 0000000..02b3c91 --- /dev/null +++ b/pactest/tests/ignore003.py @@ -0,0 +1,35 @@ +self.description = "Sync with relevant ignored packages and dependency loop" + +package1 = pmpkg("package1") +self.addpkg2db("local", package1) + +package2 = pmpkg("package2") +self.addpkg2db("local", package2) + +package3 = pmpkg("package3") +package3.depends = ["package2=1.0-1"] +self.addpkg2db("local", package3) + +package4 = pmpkg("package4") +package4.depends = ["package3=1.0-1"] +self.addpkg2db("local", package4) + +package2up = pmpkg("package2", "2.0-1") +self.addpkg2db("sync", package2up) + +package3up = pmpkg("package3", "2.0-1") +package3up.depends = ["package2=2.0-1", "package4=2.0-1"] +self.addpkg2db("sync", package3up) + +package4up = pmpkg("package4", "2.0-1") +package4up.depends = ["package3=2.0-1"] +self.addpkg2db("sync", package4up) + +self.option["IgnorePkg"] = ["package2"] +self.args = "-Su" + +self.addrule("PACMAN_RETCODE=0") +self.addrule("PKG_VERSION=package1|1.0-1") +self.addrule("PKG_VERSION=package2|1.0-1") +self.addrule("PKG_VERSION=package3|1.0-1") +self.addrule("PKG_VERSION=package4|1.0-1") diff --git a/pactest/tests/ignore004.py b/pactest/tests/ignore004.py new file mode 100644 index 0000000..fff12f6 --- /dev/null +++ b/pactest/tests/ignore004.py @@ -0,0 +1,46 @@ +self.description = "Sync with ignore causing top-level to be ignored" + +packageA1 = pmpkg("packageA1") +packageA1.depends = ["packageA2=1.0-1", "packageA3=1.0-1"]; +self.addpkg2db("local", packageA1) + +packageA2 = pmpkg("packageA2") +packageA2.depends = ["packageA4=1.0-1", "packageA5=1.0-1"]; +self.addpkg2db("local", packageA2) + +packageA3 = pmpkg("packageA3") +self.addpkg2db("local", packageA3) + +packageA4 = pmpkg("packageA4") +self.addpkg2db("local", packageA4) + +packageA5 = pmpkg("packageA5") +self.addpkg2db("local", packageA5) + +packageA1up = pmpkg("packageA1", "2.0-1") +packageA1up.depends = ["packageA2=2.0-1", "packageA3=2.0-1"]; +self.addpkg2db("sync", packageA1up) + +packageA2up = pmpkg("packageA2", "2.0-1") +packageA2up.depends = ["packageA4=2.0-1", "packageA5=2.0-1"]; +self.addpkg2db("sync", packageA2up) + +packageA3up = pmpkg("packageA3", "2.0-1") +self.addpkg2db("sync", packageA3up) + +packageA4up = pmpkg("packageA4", "2.0-1") +self.addpkg2db("sync", packageA4up) + +packageA5up = pmpkg("packageA5", "2.0-1") +self.addpkg2db("sync", packageA5up) + + +self.option["IgnorePkg"] = ["packageA3"] +self.args = "-S packageA1" + +self.addrule("PACMAN_RETCODE=0") +self.addrule("PKG_VERSION=packageA1|1.0-1") +self.addrule("PKG_VERSION=packageA2|1.0-1") +self.addrule("PKG_VERSION=packageA3|1.0-1") +self.addrule("PKG_VERSION=packageA4|1.0-1") +self.addrule("PKG_VERSION=packageA5|1.0-1") diff --git a/pactest/tests/ignore005.py b/pactest/tests/ignore005.py new file mode 100644 index 0000000..1957ea4 --- /dev/null +++ b/pactest/tests/ignore005.py @@ -0,0 +1,46 @@ +self.description = "Sync with ignore causing top-level to be included" + +packageA1 = pmpkg("packageA1") +packageA1.depends = ["packageA2>=1.0-1", "packageA3=1.0-1"]; +self.addpkg2db("local", packageA1) + +packageA2 = pmpkg("packageA2") +packageA2.depends = ["packageA4=1.0-1", "packageA5=1.0-1"]; +self.addpkg2db("local", packageA2) + +packageA3 = pmpkg("packageA3") +self.addpkg2db("local", packageA3) + +packageA4 = pmpkg("packageA4") +self.addpkg2db("local", packageA4) + +packageA5 = pmpkg("packageA5") +self.addpkg2db("local", packageA5) + +packageA1up = pmpkg("packageA1", "2.0-1") +packageA1up.depends = ["packageA2>=2.0-1", "packageA3=2.0-1"]; +self.addpkg2db("sync", packageA1up) + +packageA2up = pmpkg("packageA2", "2.0-1") +packageA2up.depends = ["packageA4=2.0-1", "packageA5=2.0-1"]; +self.addpkg2db("sync", packageA2up) + +packageA3up = pmpkg("packageA3", "2.0-1") +self.addpkg2db("sync", packageA3up) + +packageA4up = pmpkg("packageA4", "2.0-1") +self.addpkg2db("sync", packageA4up) + +packageA5up = pmpkg("packageA5", "2.0-1") +self.addpkg2db("sync", packageA5up) + + +self.option["IgnorePkg"] = ["packageA3"] +self.args = "-S packageA1 packageA2" + +self.addrule("PACMAN_RETCODE=0") +self.addrule("PKG_VERSION=packageA1|1.0-1") +self.addrule("PKG_VERSION=packageA2|2.0-1") +self.addrule("PKG_VERSION=packageA3|1.0-1") +self.addrule("PKG_VERSION=packageA4|2.0-1") +self.addrule("PKG_VERSION=packageA5|2.0-1") diff --git a/src/pacman/callback.c b/src/pacman/callback.c index d6b5b01..a31a7b4 100644 --- a/src/pacman/callback.c +++ b/src/pacman/callback.c @@ -248,15 +248,8 @@ void cb_trans_conv(pmtransconv_t event, void *data1, void *data2, { switch(event) { case PM_TRANS_CONV_INSTALL_IGNOREPKG: - if(data2) { - /* TODO we take this route based on data2 being not null? WTF */ - *response = yesno(_(":: %s requires installing %s from IgnorePkg/IgnoreGroup. Install anyway?"), - alpm_pkg_get_name(data2), - alpm_pkg_get_name(data1)); - } else { - *response = yesno(_(":: %s is in IgnorePkg/IgnoreGroup. Install anyway?"), - alpm_pkg_get_name(data1)); - } + *response = yesno(_(":: %s is in IgnorePkg/IgnoreGroup. Install anyway?"), + alpm_pkg_get_name(data1)); break; case PM_TRANS_CONV_REPLACE_PKG: *response = yesno(_(":: Replace %s with %s/%s?"), -- 1.6.1
On 22/02/2009, at 7:25 PM, Bryan Ischo wrote:
@@ -371,7 +371,8 @@ typedef enum _pmtransconv_t { PM_TRANS_CONV_REPLACE_PKG = 0x02, PM_TRANS_CONV_CONFLICT_PKG = 0x04, PM_TRANS_CONV_CORRUPTED_PKG = 0x08, - PM_TRANS_CONV_LOCAL_NEWER = 0x10 + PM_TRANS_CONV_LOCAL_NEWER = 0x10, + PM_TRANS_CONV_REMOVE_PKGS = 0x20, } pmtransconv_t;
Would be nice to document this.
Sebastian Nowicki wrote:
On 22/02/2009, at 7:25 PM, Bryan Ischo wrote:
@@ -371,7 +371,8 @@ typedef enum _pmtransconv_t { PM_TRANS_CONV_REPLACE_PKG = 0x02, PM_TRANS_CONV_CONFLICT_PKG = 0x04, PM_TRANS_CONV_CORRUPTED_PKG = 0x08, - PM_TRANS_CONV_LOCAL_NEWER = 0x10 + PM_TRANS_CONV_LOCAL_NEWER = 0x10, + PM_TRANS_CONV_REMOVE_PKGS = 0x20, } pmtransconv_t;
Would be nice to document this.
Yes, it would be nice if all of them were documented. But none of them are. I'm not trying to solve every existing problem with the pacman source. I'm just trying to add a new feature without making the code any 'worse' than it was ... And to be honest, I would be happy to add this documentation, but ... I've already constructed and re-constructed my git patches so many times to satisfy requests on this list, I'm afraid I have no more energy to do it all over again just to add some comments in a place where no comments existed previously. Sorry :( Thanks, Bryan
Bryan Ischo wrote:
@@ -371,7 +371,8 @@ typedef enum _pmtransconv_t { PM_TRANS_CONV_REPLACE_PKG = 0x02, PM_TRANS_CONV_CONFLICT_PKG = 0x04, PM_TRANS_CONV_CORRUPTED_PKG = 0x08, - PM_TRANS_CONV_LOCAL_NEWER = 0x10 + PM_TRANS_CONV_LOCAL_NEWER = 0x10, + PM_TRANS_CONV_REMOVE_PKGS = 0x20, } pmtransconv_t;
Is that new dangling comma at the end there a bad thing? Allan
On Sun, Feb 22, 2009 at 12:45 PM, Allan McRae <allan@archlinux.org> wrote:
Bryan Ischo wrote:
@@ -371,7 +371,8 @@ typedef enum _pmtransconv_t { PM_TRANS_CONV_REPLACE_PKG = 0x02, PM_TRANS_CONV_CONFLICT_PKG = 0x04, PM_TRANS_CONV_CORRUPTED_PKG = 0x08, - PM_TRANS_CONV_LOCAL_NEWER = 0x10 + PM_TRANS_CONV_LOCAL_NEWER = 0x10, + PM_TRANS_CONV_REMOVE_PKGS = 0x20, } pmtransconv_t;
Is that new dangling comma at the end there a bad thing?
A quick lookup on google tells me this is valid in C99 but not in C89 standard.
Xavier wrote:
On Sun, Feb 22, 2009 at 12:45 PM, Allan McRae <allan@archlinux.org> wrote:
Bryan Ischo wrote:
@@ -371,7 +371,8 @@ typedef enum _pmtransconv_t { PM_TRANS_CONV_REPLACE_PKG = 0x02, PM_TRANS_CONV_CONFLICT_PKG = 0x04, PM_TRANS_CONV_CORRUPTED_PKG = 0x08, - PM_TRANS_CONV_LOCAL_NEWER = 0x10 + PM_TRANS_CONV_LOCAL_NEWER = 0x10, + PM_TRANS_CONV_REMOVE_PKGS = 0x20, } pmtransconv_t;
Is that new dangling comma at the end there a bad thing?
A quick lookup on google tells me this is valid in C99 but not in C89 standard.
It was unintentional. If I recreate my patches I will fix it. If not, whoever applies my patches, can you please just fix that yourself in your tree? Or don't fix it - there isn't a compiler made in 10 years that would have problems with that comma .... Bryan
On 22/02/2009, at 8:33 PM, Bryan Ischo wrote:
Sebastian Nowicki wrote:
On 22/02/2009, at 7:25 PM, Bryan Ischo wrote:
@@ -371,7 +371,8 @@ typedef enum _pmtransconv_t { PM_TRANS_CONV_REPLACE_PKG = 0x02, PM_TRANS_CONV_CONFLICT_PKG = 0x04, PM_TRANS_CONV_CORRUPTED_PKG = 0x08, - PM_TRANS_CONV_LOCAL_NEWER = 0x10 + PM_TRANS_CONV_LOCAL_NEWER = 0x10, + PM_TRANS_CONV_REMOVE_PKGS = 0x20, } pmtransconv_t;
Would be nice to document this.
Yes, it would be nice if all of them were documented. But none of them are.
I'm not trying to solve every existing problem with the pacman source. I'm just trying to add a new feature without making the code any 'worse' than it was ...
And to be honest, I would be happy to add this documentation, but ... I've already constructed and re-constructed my git patches so many times to satisfy requests on this list, I'm afraid I have no more energy to do it all over again just to add some comments in a place where no comments existed previously. Sorry :(
I wasn't talking about fixing any problems, but rather not creating more. I only suggested that you document the field that you added, so that there would be less to document in the future. If everyone were to document code when they modify/add it, the documentation would slowly improve. I'm not a developer so my nitpicking can be safely ignored :P.
Sebastian Nowicki wrote:
Yes, it would be nice if all of them were documented. But none of them are.
I'm not trying to solve every existing problem with the pacman source. I'm just trying to add a new feature without making the code any 'worse' than it was ...
And to be honest, I would be happy to add this documentation, but ... I've already constructed and re-constructed my git patches so many times to satisfy requests on this list, I'm afraid I have no more energy to do it all over again just to add some comments in a place where no comments existed previously. Sorry :(
I wasn't talking about fixing any problems, but rather not creating more. I only suggested that you document the field that you added, so that there would be less to document in the future. If everyone were to document code when they modify/add it, the documentation would slowly improve. I'm not a developer so my nitpicking can be safely ignored :P.
I suppose it's how you look at it. If I modify a block of code that already has comments, I add comments to my changes. If I modify a block of code that does not have comments, then I don't. Someone decided originally that the block in question didn't need comments, so I just followed that lead. If I have to re-create my patches again, then I'll put the comments in there as part of that. Thanks, Bryan
On Sun, Feb 22, 2009 at 5:33 AM, Bryan Ischo <bji-keyword-pacman.3644cb@www.ischo.com> wrote:
I'm not trying to solve every existing problem with the pacman source. I'm just trying to add a new feature without making the code any 'worse' than it was ...
And to be honest, I would be happy to add this documentation, but ... I've already constructed and re-constructed my git patches so many times to satisfy requests on this list, I'm afraid I have no more energy to do it all over again just to add some comments in a place where no comments existed previously. Sorry :(
Just out of curiousity, how have you been making changes to your patches? You do know git makes this quite painless with tools like rebase and rebase -i. Part of the reason we make so many requests is because changing patches is not a big deal with git, but if you don't use the tools to your advantage I could see it being painful. -Dan
Dan McGee wrote:
On Sun, Feb 22, 2009 at 5:33 AM, Bryan Ischo <bji-keyword-pacman.3644cb@www.ischo.com> wrote:
I'm not trying to solve every existing problem with the pacman source. I'm just trying to add a new feature without making the code any 'worse' than it was ...
And to be honest, I would be happy to add this documentation, but ... I've already constructed and re-constructed my git patches so many times to satisfy requests on this list, I'm afraid I have no more energy to do it all over again just to add some comments in a place where no comments existed previously. Sorry :(
Just out of curiousity, how have you been making changes to your patches? You do know git makes this quite painless with tools like rebase and rebase -i. Part of the reason we make so many requests is because changing patches is not a big deal with git, but if you don't use the tools to your advantage I could see it being painful.
Well I find git to be kind of painful, to be honest. Maybe I'm not using it correctly? Every git command is very fast, but there are so many of them to run as part of recreating patches, and so many little details to get right every time. First problem is that it's not possible to be in two branches at once. If my branches were rooted at different subdirectories of my tree, then I could have all versions of all of my files in place in my filesystem and easily look at different versions. As it is, I have to re-read man pages to see how to cat versions of files from different branches while I am working on a given branch. It's a bit of a pain to keep track of everything in this way, and I believe that if different branches were stored in different parts of your tree and you didn't have to use git to switch your view between them all the time, things would be easier. This is how Perforce, and from my reading of documentation, Bazaar works, and for me personally, it would be a vast improvement over the git workflow. The way that I incorporate feedback from the list is: - I have a branch that has my most-recently-sent patches in it. Call that branch 'old'. - I create a new branch off of master, call that branch 'new' - I find out what the change number of the first change that I need to update is, and I do 'git merge --no-commit <change_number>', to get the first change into my new branch. - I don't know why, but unless there are conflicts, git ignores my --no-commit most of the time and commits anyway. So I then do git reset HEAD^. - Now I'm sitting at a tree with the same modifications that my first patch had. Now I have to go open multiple emails and scan through them, checking to see what changes I need to make to that patch, and making them. - Then I have to run tests and also run pacman manually to make sure that my changes to my patch didn't introduce any problem. Usually I just make clean and rebuild everything all the time because I am paranoid that the make rules, combined with git changing files 'in place' in my filesystem, will not recompile everything correctly. I have no reason to believe this, but I'm just paranoid so I always do a clean before a make. - Finally, I can check in my change. I do git commit -s, and then open the log for my commit to the 'old' branch in a separate window so that I can copy over my commit message, changing it as necessary also. - Then, I repeat the above for the next patch(es) in sequence. Often there are conflicts when merging these in, because of the changes that I made to the previous patches in the sequence, and I have to deal with that too. - Any small error in this process results in messed up patches. Invariably, I realize mistakes and have to repeat the whole process, starting with a new branch, applying the first patch, etc, etc, over and over again, as I realize that my change forgot to add a file, or that I missing some small thing. I must just have fumbling fingers, but it takes me at least 3 or 4 tries every single time to get the 'perfect' patches. - Finally, I git format-patch to get patches to send. I use git send-email to send them to myself, so that I can then create a new branch off of master, and apply them one by one to ensure that they apply cleanly. If so, I use git send-email to send them to the pacman-dev list. The whole process takes hours. The most frustrating aspect is how perfectly everything has to be done or the patch will be wrong, and once a wrong patch is in, I have to start all or part of the process over. Then, I send what I think is the perfect patches to the list, and I get feedback and find that I have to do the whole thing all over again, and again, and again ... Thanks, Bryan
On Mon, Feb 23, 2009 at 08:34:59AM +1300, Bryan Ischo wrote:
Well I find git to be kind of painful, to be honest. Maybe I'm not using it correctly? Every git command is very fast, but there are so many of them to run as part of recreating patches, and so many little details to get right every time.
Have a look at `man git-rebase` If you're in a branch called 'old' and want to update your patches to apply cleanly to master you would just do `git rebase master`. Files with conflicts will have special markers similar to what svn does when there are conflicts updating or merging like: Just edit the file so the patch is as you intend, and continue with the rebase. <<<<<<< HEAD:README Blah foo ======= Blah bar bar
> Put some bar after the Blah.:README
Cheers.
Loui Chang wrote:
On Mon, Feb 23, 2009 at 08:34:59AM +1300, Bryan Ischo wrote:
Well I find git to be kind of painful, to be honest. Maybe I'm not using it correctly? Every git command is very fast, but there are so many of them to run as part of recreating patches, and so many little details to get right every time.
Have a look at `man git-rebase`
If you're in a branch called 'old' and want to update your patches to apply cleanly to master you would just do `git rebase master`.
Files with conflicts will have special markers similar to what svn does when there are conflicts updating or merging like:
Just edit the file so the patch is as you intend, and continue with the rebase.
Thanks for the tip. So using git-rebase is the better way to incorporate feedback into patches? It's not just that I'm trying to make my existing patches apply cleanly on some other branch. It's that I have to 'redo' the changes because I have to incorporate feedback and make modifications to the changes from which the patches originally were derived. So git-rebase will help me with this? I've used git-rebase before, but only to bring unmodified patches from one branch to another, or from one part of a branch to another part (once I have sent out patches and they haven't gone into the official git repository yet, I use git-rebase in my own git tree to occasionally bring the patches forward past all of the changes that I pull in from the master repository, so that I can be sure that they would cleanly apply without changes to the master repository), but I've never considered using it to allow me to re-stage patches and modify them in place. Thanks, Bryan
Bryan Ischo wrote:
Loui Chang wrote:
On Mon, Feb 23, 2009 at 08:34:59AM +1300, Bryan Ischo wrote:
Well I find git to be kind of painful, to be honest. Maybe I'm not using it correctly? Every git command is very fast, but there are so many of them to run as part of recreating patches, and so many little details to get right every time.
Have a look at `man git-rebase`
If you're in a branch called 'old' and want to update your patches to apply cleanly to master you would just do `git rebase master`.
Files with conflicts will have special markers similar to what svn does when there are conflicts updating or merging like:
Just edit the file so the patch is as you intend, and continue with the rebase.
Thanks for the tip. So using git-rebase is the better way to incorporate feedback into patches? It's not just that I'm trying to make my existing patches apply cleanly on some other branch. It's that I have to 'redo' the changes because I have to incorporate feedback and make modifications to the changes from which the patches originally were derived. So git-rebase will help me with this?
I've used git-rebase before, but only to bring unmodified patches from one branch to another, or from one part of a branch to another part (once I have sent out patches and they haven't gone into the official git repository yet, I use git-rebase in my own git tree to occasionally bring the patches forward past all of the changes that I pull in from the master repository, so that I can be sure that they would cleanly apply without changes to the master repository), but I've never considered using it to allow me to re-stage patches and modify them in place.
OK so I've played with git-rebase a little bit and I can see how it's better than git-merge for getting changes into a new branch so that they can be modified. But I think I'd still have to do "git reset HEAD^" and then modify my changes and check the modifications in, and all the other steps, right? Thanks, Bryan
Bryan Ischo wrote:
OK so I've played with git-rebase a little bit and I can see how it's better than git-merge for getting changes into a new branch so that they can be modified. But I think I'd still have to do "git reset HEAD^" and then modify my changes and check the modifications in, and all the other steps, right?
Thanks, Bryan
Meh. I checked in my git-rebased change, then git reset HEAD^, then modified the change and checked it back in. Then I tried git-rebase to get my next change in the sequence, and I got a zillion weird conflict problems. I don't think you can git-rebase multiple changes iteratively, making changes in between. Or if you can, maybe I'm just not using it right ... Thanks, Bryan
On Sun, Feb 22, 2009 at 9:41 PM, Bryan Ischo <bji-keyword-pacman.3644cb@www.ischo.com> wrote:
Bryan Ischo wrote:
Thanks for the tip. So using git-rebase is the better way to incorporate feedback into patches? It's not just that I'm trying to make my existing patches apply cleanly on some other branch. It's that I have to 'redo' the changes because I have to incorporate feedback and make modifications to the changes from which the patches originally were derived. So git-rebase will help me with this?
I've used git-rebase before, but only to bring unmodified patches from one branch to another, or from one part of a branch to another part (once I have sent out patches and they haven't gone into the official git repository yet, I use git-rebase in my own git tree to occasionally bring the patches forward past all of the changes that I pull in from the master repository, so that I can be sure that they would cleanly apply without changes to the master repository), but I've never considered using it to allow me to re-stage patches and modify them in place.
OK so I've played with git-rebase a little bit and I can see how it's better than git-merge for getting changes into a new branch so that they can be modified. But I think I'd still have to do "git reset HEAD^" and then modify my changes and check the modifications in, and all the other steps, right?
I am sure you read the wiki, right? :) http://wiki.archlinux.org/index.php/Pacman_Development Before using the git cheat sheet, it is highly recommended to read the Super_Quick_Git_Guide http://wiki.archlinux.org/index.php/Super_Quick_Git_Guide http://wiki.archlinux.org/index.php/Super_Quick_Git_Guide#Fixing_your_patch
Xavier wrote:
I am sure you read the wiki, right? :) http://wiki.archlinux.org/index.php/Pacman_Development Before using the git cheat sheet, it is highly recommended to read the Super_Quick_Git_Guide http://wiki.archlinux.org/index.php/Super_Quick_Git_Guide http://wiki.archlinux.org/index.php/Super_Quick_Git_Guide#Fixing_your_patch _______________________________________________
Yes, I read those pages, initially. I guess much of it didn't sink in at the time because I haven't been using this process to update patches, as suggested by the super quick git guide: git rebase -i <sha1 from above> (edit the text file that appears so 'edit' appears next to the commit you wish to modify) (edit the required files) git add -u git commit --amend git rebase --continue To be honest, this isn't a whole lot better in terms of number of git commands to run, or things to screw up, as my "create new branch, merge changes in one at a time, fix, and recommit them" process, but if it's the standard way, then I'll do it. The hard parts of getting all of the little details in the changes right, and having to repeat the process if I make any mistakes, plus rebulding, running tests, etc, between each change, all are still required. Thanks, Bryan
On 23/02/2009, at 5:55 AM, Bryan Ischo wrote:
To be honest, this isn't a whole lot better in terms of number of git commands to run, or things to screw up, as my "create new branch, merge changes in one at a time, fix, and recommit them" process, but if it's the standard way, then I'll do it.
The hard parts of getting all of the little details in the changes right, and having to repeat the process if I make any mistakes, plus rebulding, running tests, etc, between each change, all are still required.
You're workflow seems overfly complicated. What I do is simply keep committing on top of the previous commits: - In my new branch I make the initial commit - I run `git format-patch HEAD^`, and send the patch off. - When I get feedback I make the changes and keep committing. - When it's time to submit again, I either make a new branch from merge and `git merge --squash my_branch` (this lets me keep the history on the other branch in case I need to revert), or simply `git rebase -i FIRST_COMMIT^` (where FIRST_COMMIT is the original commit for the branch) and squash the commits. - The last thing to do is `git format-patch` and send it off again. All very simple. I'm not sure that you'd find an SCM which makes this easier. More briefly: git checkout -b my_branch master #edit git commit -s -m "My awesome feature" git format-patch HEAD^ git send-email --to foo@bar.org 0001*.patch # Get feedback # Edit git commit -m "Fixed something" # Edit git commit -m "Fixed something else" git checkout -b squash_my_branch master git merge --squash my_branch git commit -s # Editing the commit message is somewhat annoying, rebase doesn't have this problem. rm -f 0001*.patch git format-patch HEAD^ git send-email --to foo@bar.org 0001*.patch
On Sun, Feb 22, 2009 at 9:35 PM, Sebastian Nowicki <sebnow@gmail.com> wrote:
On 23/02/2009, at 5:55 AM, Bryan Ischo wrote:
To be honest, this isn't a whole lot better in terms of number of git commands to run, or things to screw up, as my "create new branch, merge changes in one at a time, fix, and recommit them" process, but if it's the standard way, then I'll do it.
The hard parts of getting all of the little details in the changes right, and having to repeat the process if I make any mistakes, plus rebulding, running tests, etc, between each change, all are still required.
You're workflow seems overfly complicated. What I do is simply keep committing on top of the previous commits:
- In my new branch I make the initial commit - I run `git format-patch HEAD^`, and send the patch off. - When I get feedback I make the changes and keep committing. - When it's time to submit again, I either make a new branch from merge and `git merge --squash my_branch` (this lets me keep the history on the other branch in case I need to revert), or simply `git rebase -i FIRST_COMMIT^` (where FIRST_COMMIT is the original commit for the branch) and squash the commits. - The last thing to do is `git format-patch` and send it off again. All very simple. I'm not sure that you'd find an SCM which makes this easier.
Exactly what I was trying to get across. The power that 'rebase -i' + squash gives you makes this _so_ easy. -Dan
Dan McGee wrote:
On Sun, Feb 22, 2009 at 9:35 PM, Sebastian Nowicki <sebnow@gmail.com> wrote:
On 23/02/2009, at 5:55 AM, Bryan Ischo wrote:
To be honest, this isn't a whole lot better in terms of number of git commands to run, or things to screw up, as my "create new branch, merge changes in one at a time, fix, and recommit them" process, but if it's the standard way, then I'll do it.
The hard parts of getting all of the little details in the changes right, and having to repeat the process if I make any mistakes, plus rebulding, running tests, etc, between each change, all are still required.
You're workflow seems overfly complicated. What I do is simply keep committing on top of the previous commits:
- In my new branch I make the initial commit - I run `git format-patch HEAD^`, and send the patch off. - When I get feedback I make the changes and keep committing. - When it's time to submit again, I either make a new branch from merge and `git merge --squash my_branch` (this lets me keep the history on the other branch in case I need to revert), or simply `git rebase -i FIRST_COMMIT^` (where FIRST_COMMIT is the original commit for the branch) and squash the commits. - The last thing to do is `git format-patch` and send it off again. All very simple. I'm not sure that you'd find an SCM which makes this easier.
Exactly what I was trying to get across.
The power that 'rebase -i' + squash gives you makes this _so_ easy.
-Dan _____
The wrinkle that makes things more complicated is that I was required to make my changes into three separate patches. So I have to maintain those changes as separate patches, and the --squash doesn't really help me. It's keeping the patches separate, while incorporating list feedback into each patch individually, that is hard to manage. Bryan
On Sun, Feb 22, 2009 at 9:44 PM, Bryan Ischo <bji-keyword-pacman.3644cb@www.ischo.com> wrote:
Dan McGee wrote:
On Sun, Feb 22, 2009 at 9:35 PM, Sebastian Nowicki <sebnow@gmail.com> wrote:
On 23/02/2009, at 5:55 AM, Bryan Ischo wrote:
To be honest, this isn't a whole lot better in terms of number of git commands to run, or things to screw up, as my "create new branch, merge changes in one at a time, fix, and recommit them" process, but if it's the standard way, then I'll do it.
The hard parts of getting all of the little details in the changes right, and having to repeat the process if I make any mistakes, plus rebulding, running tests, etc, between each change, all are still required.
You're workflow seems overfly complicated. What I do is simply keep committing on top of the previous commits:
- In my new branch I make the initial commit - I run `git format-patch HEAD^`, and send the patch off. - When I get feedback I make the changes and keep committing. - When it's time to submit again, I either make a new branch from merge and `git merge --squash my_branch` (this lets me keep the history on the other branch in case I need to revert), or simply `git rebase -i FIRST_COMMIT^` (where FIRST_COMMIT is the original commit for the branch) and squash the commits. - The last thing to do is `git format-patch` and send it off again. All very simple. I'm not sure that you'd find an SCM which makes this easier.
Exactly what I was trying to get across.
The power that 'rebase -i' + squash gives you makes this _so_ easy.
-Dan _____
The wrinkle that makes things more complicated is that I was required to make my changes into three separate patches. So I have to maintain those changes as separate patches, and the --squash doesn't really help me. It's keeping the patches separate, while incorporating list feedback into each patch individually, that is hard to manage.
Completely false though! rebase -i lets you do a ton of things: If I'm presented with this when running "git rebase -i master": pick 42bb511 Add support for sleep command pick f1d477b Fix setting of low volume levels pick b3598cd Update comment pick 0f37e11 Add ability to control sleep timer from the frontend pick b3b64c7 Add concept of epoch to frontend pick 6285fc2 Don't record last sent time # Rebase d189b6a..6285fc2 onto d189b6a # # Commands: # p, pick = use commit # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # # If you remove a line here THAT COMMIT WILL BE LOST. # However, if you remove everything, the rebase will be aborted. # I can do something like this (note the reordering and the command switching): pick 0f37e11 Add ability to control sleep timer from the frontend squash 42bb511 Add support for sleep command pick f1d477b Fix setting of low volume levels edit b3b64c7 Add concept of epoch to frontend pick 6285fc2 Don't record last sent time squash b3598cd Update comment And I'll end up with four new patches, ready to do whatever with. Multiple patch or single patch, it doesn't matter. I never use git-merge when doing my own work, btw- I'm really not sure that makes workflow easy at all, as I tend to cherrypick things around on multiple working branches if I want to move patches. -Dan
Dan McGee wrote:
The wrinkle that makes things more complicated is that I was required to make my changes into three separate patches. So I have to maintain those changes as separate patches, and the --squash doesn't really help me. It's keeping the patches separate, while incorporating list feedback into each patch individually, that is hard to manage.
Completely false though! rebase -i lets you do a ton of things:
If I'm presented with this when running "git rebase -i master":
pick 42bb511 Add support for sleep command pick f1d477b Fix setting of low volume levels pick b3598cd Update comment pick 0f37e11 Add ability to control sleep timer from the frontend pick b3b64c7 Add concept of epoch to frontend pick 6285fc2 Don't record last sent time
# Rebase d189b6a..6285fc2 onto d189b6a # # Commands: # p, pick = use commit # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # # If you remove a line here THAT COMMIT WILL BE LOST. # However, if you remove everything, the rebase will be aborted. #
I can do something like this (note the reordering and the command switching):
pick 0f37e11 Add ability to control sleep timer from the frontend squash 42bb511 Add support for sleep command pick f1d477b Fix setting of low volume levels edit b3b64c7 Add concept of epoch to frontend pick 6285fc2 Don't record last sent time squash b3598cd Update comment
And I'll end up with four new patches, ready to do whatever with. Multiple patch or single patch, it doesn't matter.
I never use git-merge when doing my own work, btw- I'm really not sure that makes workflow easy at all, as I tend to cherrypick things around on multiple working branches if I want to move patches.
OK, so I guess I really need to get into the habit of using git-rebase -i. One question: I should do the rebase -i onto a new branch, right, so as not to disturb my existing branch? Because if I make a mistake, I want to be able to recover by blowing away the branch I was rebasing into, and starting over with a new one. Does that make sense? Thanks, Bryan
On Sun, Feb 22, 2009 at 9:57 PM, Bryan Ischo <bji-keyword-pacman.3644cb@www.ischo.com> wrote:
Dan McGee wrote:
The wrinkle that makes things more complicated is that I was required to make my changes into three separate patches. So I have to maintain those changes as separate patches, and the --squash doesn't really help me. It's keeping the patches separate, while incorporating list feedback into each patch individually, that is hard to manage.
Completely false though! rebase -i lets you do a ton of things:
If I'm presented with this when running "git rebase -i master":
pick 42bb511 Add support for sleep command pick f1d477b Fix setting of low volume levels pick b3598cd Update comment pick 0f37e11 Add ability to control sleep timer from the frontend pick b3b64c7 Add concept of epoch to frontend pick 6285fc2 Don't record last sent time
# Rebase d189b6a..6285fc2 onto d189b6a # # Commands: # p, pick = use commit # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # # If you remove a line here THAT COMMIT WILL BE LOST. # However, if you remove everything, the rebase will be aborted. #
I can do something like this (note the reordering and the command switching):
pick 0f37e11 Add ability to control sleep timer from the frontend squash 42bb511 Add support for sleep command pick f1d477b Fix setting of low volume levels edit b3b64c7 Add concept of epoch to frontend pick 6285fc2 Don't record last sent time squash b3598cd Update comment
And I'll end up with four new patches, ready to do whatever with. Multiple patch or single patch, it doesn't matter.
I never use git-merge when doing my own work, btw- I'm really not sure that makes workflow easy at all, as I tend to cherrypick things around on multiple working branches if I want to move patches.
OK, so I guess I really need to get into the habit of using git-rebase -i.
One question: I should do the rebase -i onto a new branch, right, so as not to disturb my existing branch? Because if I make a mistake, I want to be able to recover by blowing away the branch I was rebasing into, and starting over with a new one. Does that make sense?
Nope. You modify the branch you want to modify. I think that is where you are making it harder on yourself than you need to, as you are attempting to do work that git already does for you. If you fuck something up, try typing 'git reflog show <branchname>'. You will see every point that branch has been known as for at least the last 30 days. If I screw something up, I can open up that reflog, grab the partial sha1, and just do a "git reset --hard <sha1>" to bring my branch back to that exact state. -Dan
On 23/02/2009, at 12:57 PM, Bryan Ischo wrote:
OK, so I guess I really need to get into the habit of using git- rebase -i.
Yes, git rebase is one of the most wonderful things about git. It really makes git flexible. Remember never to rebase on published commits though, as that would screw things up for people who pulled from you already. Of course there's no problem with that when sending patches.
One question: I should do the rebase -i onto a new branch, right, so as not to disturb my existing branch? Because if I make a mistake, I want to be able to recover by blowing away the branch I was rebasing into, and starting over with a new one.
You could do that, but there's also git reflog, which shows where your HEAD has been. If you screw something up, you can find the correct HEAD and attach it to a branch. It's git's safety net of sorts. I haven't actually done that so I am unsure as to how effective it would be, but it's there, and it has saved me a few times.
On Sun, Feb 22, 2009 at 10:12 PM, Sebastian Nowicki <sebnow@gmail.com> wrote:
On 23/02/2009, at 12:57 PM, Bryan Ischo wrote:
OK, so I guess I really need to get into the habit of using git-rebase -i.
Yes, git rebase is one of the most wonderful things about git.
git rebase -i, git add -p, and git stash are my three most "omg awesome" git commands.
Aaron Griffin wrote:
On Sun, Feb 22, 2009 at 10:12 PM, Sebastian Nowicki <sebnow@gmail.com> wrote:
On 23/02/2009, at 12:57 PM, Bryan Ischo wrote:
OK, so I guess I really need to get into the habit of using git-rebase -i.
Yes, git rebase is one of the most wonderful things about git.
git rebase -i, git add -p, and git stash are my three most "omg awesome" git commands.
Just curious ... what's so awesome about git stash? It seems to me that it is only necessary because git doesn't support multiple branches in the same tree. The Perforce (and some DVCS systems like Bazaar) way is to root each branch at a different subdirectory of your repository top-level directory in your local filesystem. Then you can work on files in multiple branches simultaneously without having to 'switch' your view between them constantly, 'stashing' and 'unstashing' changes all the time. Honestly, there are two things which I think suck about git (I realize that many things that have been difficult for me have simply been from my lack of knowledge of git, so I don't consider those things sucky, they're just things I need to learn; but the following things actually do suck): - A single branch-based 'view' that switches your files around in-place as you change which branch you are on, instead of keeping branches in separate subdirectories - Lack of rename tracking. Yeah, I know, git claims that it can do it after the fact when examining change histories but I've tried various scenarios and it just doesn't work very well, and even when it does, requires stupidly complex options to git commands to enable git to discover renames in the history correctly I think the ideal DVCS would have the semantics of Bazaar, but with the speed of git. I think this could be accomplished if Bazaar were written in C or C++ instead of Python - having to start up the Python interpreter for every single Bazaar command is ... unfortunate. And from what I've read, Bazaar has real performance problems with large trees or long histories. Thanks, Bryan
On Mon, Feb 23, 2009 at 1:11 PM, Bryan Ischo <bji-keyword-pacman.3644cb@www.ischo.com> wrote:
Aaron Griffin wrote:
On Sun, Feb 22, 2009 at 10:12 PM, Sebastian Nowicki <sebnow@gmail.com> wrote:
On 23/02/2009, at 12:57 PM, Bryan Ischo wrote:
OK, so I guess I really need to get into the habit of using git-rebase -i.
Yes, git rebase is one of the most wonderful things about git.
git rebase -i, git add -p, and git stash are my three most "omg awesome" git commands.
Just curious ... what's so awesome about git stash? It seems to me that it is only necessary because git doesn't support multiple branches in the same tree. The Perforce (and some DVCS systems like Bazaar) way is to root each branch at a different subdirectory of your repository top-level directory in your local filesystem. Then you can work on files in multiple branches simultaneously without having to 'switch' your view between them constantly, 'stashing' and 'unstashing' changes all the time.
I use git stash when switching back and forth between branches when I am of the mindset that "oh this isn't commit-able yet". I keep noticing you mention "multiple branches in the same tree", but am at a loss as to why that's necessary. git offers the same functionality, mainly due to the fact that a "git checkout" is as quick as a "cd". git co master ...change... commit git co branch-a ...change... commit ..change.. stash git co master git stash --apply commit I guess I can't think of a good use-case when you would want to edit foo.c from BOTH master and branch-a at the exact same time... it seems like an attention killer to me. Like watching two TVs at once or something. Could you explain why you would need the files side-by-side?
- A single branch-based 'view' that switches your files around in-place as you change which branch you are on, instead of keeping branches in separate subdirectories
See above - I don't get how this is a con, as branch switching in git is painfully quick
- Lack of rename tracking. Yeah, I know, git claims that it can do it after the fact when examining change histories but I've tried various scenarios and it just doesn't work very well, and even when it does, requires stupidly complex options to git commands to enable git to discover renames in the history correctly
git is focused on file contents, and doesn't really care where those contents actually are. It seems odd to me too, but I have yet to discover a case when this is a big deal - I mean if I'm looking at some C code, I don't care if the file is named something.c or SOEMTHING.c or omgwtf.c - it's the code that matters.
Aaron Griffin wrote:
I use git stash when switching back and forth between branches when I am of the mindset that "oh this isn't commit-able yet".
I keep noticing you mention "multiple branches in the same tree", but am at a loss as to why that's necessary. git offers the same functionality, mainly due to the fact that a "git checkout" is as quick as a "cd".
git co master ...change... commit git co branch-a ...change... commit ..change.. stash git co master git stash --apply commit
I guess I can't think of a good use-case when you would want to edit foo.c from BOTH master and branch-a at the exact same time... it seems like an attention killer to me. Like watching two TVs at once or something.
Could you explain why you would need the files side-by-side?
It's not the ability to modify a single file in two different places at once. It's the ability to keep changes logically separated by directory, in a persistent manner that doesn't require git commands to put changes away and bring them back, that I care about. I find it infinitely easier to keep track of what I am doing by persistently retaining directory contents than by having a single working view and everything else being stashed away to be retrieved later. One example of where git stash is more cumbersome is if you've created new files but haven't added them to the index yet. You have to add them to the index before you can stash. Now this is not a huge deal, but it does require more work to prep your tree for a stash than simply cd'ing out to another branch directory would take. There may be other cases where more work is involved in stashing (above and beyond having to actually run the git stash commands and maintain the list of stashes) than is involved in using locally stored branches, but I haven't used git stash enough to discover them. It would not surprise me to learn that there are lots of subtle details to be aware of when using git stash. Parallel branch directories have an advantage over git's branch views whenever you need to compare the contents of branches. With parallel branch directories, all of the contents are there so you can compare them however you want. Additionally, you can compare things with parallel branch directories that you can't compare easily with git: for example, if I have a branch with a bug fix on it, and I want to compare the behavior of my program with the behavior of my program without that bug fix, or maybe with a different bug fix, I can build both in parallel and run them however I need to to make these comparisons. With git I guess I'd have to make my bug fix, build it, stash the code and copy the build directory somewhere else, then checkout the other branch, and build it, and then I could compare what I have just built with what I copied away somewhere else. But then if I want to make a quick change in the other branch and see how it affects the program output, I'd have to run a bunch more git commands and do lots more juggling to get back to the other brach, make the change, compile it, copy the results elsewhere, re-stash, un-stash, etc etc. Maybe it's because I'm an emacs user and not a vi user, but I don't like to keep track of any more stuff in my head than I need to. And keeping track of what changes I've stashed away from which branches and what sequence of git commands I need to run to return myself to a prior state when I was working on something else, is just more mental effort than I want to undertake. I find it so much easier to just leave a branch subdirectory and when I return to it later, it is guaranteed to be exactly as it was when I left, without any effort on my part. If I am working on 4 or 5 bugs in parallel (which I have certainly done at work, where working on just 1 or 2 bugs at once would be inefficient because of the downtime associated with building each tree) I can't even imagine using git stashes to sanely keep track of everything.
- A single branch-based 'view' that switches your files around in-place as you change which branch you are on, instead of keeping branches in separate subdirectories
See above - I don't get how this is a con, as branch switching in git is painfully quick
If quickness is all that matters, then I can guarantee that a simple 'cd' is even faster than git, no matter how fast git is. But quickness is not all that matters, and as I have described above, being able to view branches in parallel, and work on them in parallel, without any intervening git commands or mental effort in juggling stashes, and with the ability to keep parallel builds and use the build results in parallel, are much more important and for me, greatly favor parallel local branches.
- Lack of rename tracking. Yeah, I know, git claims that it can do it after the fact when examining change histories but I've tried various scenarios and it just doesn't work very well, and even when it does, requires stupidly complex options to git commands to enable git to discover renames in the history correctly
git is focused on file contents, and doesn't really care where those contents actually are. It seems odd to me too, but I have yet to discover a case when this is a big deal - I mean if I'm looking at some C code, I don't care if the file is named something.c or SOEMTHING.c or omgwtf.c - it's the code that matters.
The problem comes when someone, in a branch, renames a file, and then tries to merge their changes into another branch in which the file was not renamed. Unless file renames are tracked, the merge becomes very difficult. Refactoring a subsystem on a 'workbranch' is something that is done sometimes on large projects, and with git, I would expect that to be basically impossible to do sanely. Even if git's 'detect renames while examining history' technique did work, it still makes renames cumbersome, because you can't rename a file and change its contents at the same time or else git has almost no chance of detecting the rename via history. And if you can't change a file and rename it at the same time, then you can't, for example, properly rename a Java class, because the class name and file name have to be the same. So you'd have to rename the file (thus breaking the build, because the file would no longer compile), check that in, and live with having a broken build for a bit until you modified the file's contents to match its new name, tested it, and checked that in. It just shouldn't be that hard. File names are part of the metadata that is relevent to versioning. So the version control system should track file names properly, along with every other thing about a file (such as its contents and permissions). The fact that git doesn't do this is a serious oversight and I guarantee that eventually the git developers will have to face this and make some major changes to git. Either that, or they will just stubbornly refuse in the face of valid reasoning to the contrary. Bryan
On Tue, Feb 24, 2009 at 10:10:53AM +1300, Bryan Ischo wrote:
It's not the ability to modify a single file in two different places at once. It's the ability to keep changes logically separated by directory, in a persistent manner that doesn't require git commands to put changes away and bring them back, that I care about. I find it infinitely easier to keep [snip snip]
Duuuude. All I can say is, play around with git, read the docs thoroughly. If you really can't grasp it, or have a problem with it you might want to go through the git channels, and don't make your emails too long-winded. Cheers.
Loui Chang wrote:
On Tue, Feb 24, 2009 at 10:10:53AM +1300, Bryan Ischo wrote:
It's not the ability to modify a single file in two different places at once. It's the ability to keep changes logically separated by directory, in a persistent manner that doesn't require git commands to put changes away and bring them back, that I care about. I find it infinitely easier to keep
[snip snip]
Duuuude. All I can say is, play around with git, read the docs thoroughly. If you really can't grasp it, or have a problem with it you might want to go through the git channels, and don't make your emails too long-winded.
Cheers.
Whatever. Is that short enough? Bryan
On Mon, Feb 23, 2009 at 3:10 PM, Bryan Ischo <bji-keyword-pacman.3644cb@www.ischo.com> wrote:
Aaron Griffin wrote:
I use git stash when switching back and forth between branches when I am of the mindset that "oh this isn't commit-able yet".
I keep noticing you mention "multiple branches in the same tree", but am at a loss as to why that's necessary. git offers the same functionality, mainly due to the fact that a "git checkout" is as quick as a "cd".
git co master ...change... commit git co branch-a ...change... commit ..change.. stash git co master git stash --apply commit
I guess I can't think of a good use-case when you would want to edit foo.c from BOTH master and branch-a at the exact same time... it seems like an attention killer to me. Like watching two TVs at once or something.
Could you explain why you would need the files side-by-side?
It's not the ability to modify a single file in two different places at once. It's the ability to keep changes logically separated by directory, in a persistent manner that doesn't require git commands to put changes away and bring them back, that I care about. I find it infinitely easier to keep track of what I am doing by persistently retaining directory contents than by having a single working view and everything else being stashed away to be retrieved later.
One example of where git stash is more cumbersome is if you've created new files but haven't added them to the index yet. You have to add them to the index before you can stash. Now this is not a huge deal, but it does require more work to prep your tree for a stash than simply cd'ing out to another branch directory would take. There may be other cases where more work is involved in stashing (above and beyond having to actually run the git stash commands and maintain the list of stashes) than is involved in using locally stored branches, but I haven't used git stash enough to discover them. It would not surprise me to learn that there are lots of subtle details to be aware of when using git stash.
Parallel branch directories have an advantage over git's branch views whenever you need to compare the contents of branches. With parallel branch directories, all of the contents are there so you can compare them however you want. Additionally, you can compare things with parallel branch directories that you can't compare easily with git: for example, if I have a branch with a bug fix on it, and I want to compare the behavior of my program with the behavior of my program without that bug fix, or maybe with a different bug fix, I can build both in parallel and run them however I need to to make these comparisons. With git I guess I'd have to make my bug fix, build it, stash the code and copy the build directory somewhere else, then checkout the other branch, and build it, and then I could compare what I have just built with what I copied away somewhere else. But then if I want to make a quick change in the other branch and see how it affects the program output, I'd have to run a bunch more git commands and do lots more juggling to get back to the other brach, make the change, compile it, copy the results elsewhere, re-stash, un-stash, etc etc.
Maybe it's because I'm an emacs user and not a vi user, but I don't like to keep track of any more stuff in my head than I need to. And keeping track of what changes I've stashed away from which branches and what sequence of git commands I need to run to return myself to a prior state when I was working on something else, is just more mental effort than I want to undertake. I find it so much easier to just leave a branch subdirectory and when I return to it later, it is guaranteed to be exactly as it was when I left, without any effort on my part. If I am working on 4 or 5 bugs in parallel (which I have certainly done at work, where working on just 1 or 2 bugs at once would be inefficient because of the downtime associated with building each tree) I can't even imagine using git stashes to sanely keep track of everything.
- A single branch-based 'view' that switches your files around in-place as you change which branch you are on, instead of keeping branches in separate subdirectories
See above - I don't get how this is a con, as branch switching in git is painfully quick
If quickness is all that matters, then I can guarantee that a simple 'cd' is even faster than git, no matter how fast git is. But quickness is not all that matters, and as I have described above, being able to view branches in parallel, and work on them in parallel, without any intervening git commands or mental effort in juggling stashes, and with the ability to keep parallel builds and use the build results in parallel, are much more important and for me, greatly favor parallel local branches.
- Lack of rename tracking. Yeah, I know, git claims that it can do it after the fact when examining change histories but I've tried various scenarios and it just doesn't work very well, and even when it does, requires stupidly complex options to git commands to enable git to discover renames in the history correctly
git is focused on file contents, and doesn't really care where those contents actually are. It seems odd to me too, but I have yet to discover a case when this is a big deal - I mean if I'm looking at some C code, I don't care if the file is named something.c or SOEMTHING.c or omgwtf.c - it's the code that matters.
The problem comes when someone, in a branch, renames a file, and then tries to merge their changes into another branch in which the file was not renamed. Unless file renames are tracked, the merge becomes very difficult. Refactoring a subsystem on a 'workbranch' is something that is done sometimes on large projects, and with git, I would expect that to be basically impossible to do sanely. Even if git's 'detect renames while examining history' technique did work, it still makes renames cumbersome, because you can't rename a file and change its contents at the same time or else git has almost no chance of detecting the rename via history. And if you can't change a file and rename it at the same time, then you can't, for example, properly rename a Java class, because the class name and file name have to be the same. So you'd have to rename the file (thus breaking the build, because the file would no longer compile), check that in, and live with having a broken build for a bit until you modified the file's contents to match its new name, tested it, and checked that in.
It just shouldn't be that hard. File names are part of the metadata that is relevent to versioning. So the version control system should track file names properly, along with every other thing about a file (such as its contents and permissions). The fact that git doesn't do this is a serious oversight and I guarantee that eventually the git developers will have to face this and make some major changes to git. Either that, or they will just stubbornly refuse in the face of valid reasoning to the contrary.
I dunno, I don't see this as a problem because it's just not the way my workflow works. I make heavy use of git (well, git svn) at work, on huge amounts of code, and never run into these issues. I just tried the rename case and it worked perfectly fine. http://code.phraktured.net/cgit.cgi/foobar/ branch-a was made off the first commit, all changes were done and committed, then I switched back to master, renamed a file I changed _twice_ in branch-a, switched back to branch-a and did a "git rebase master". You can see the results there. It even lists the new file name in the diffs http://code.phraktured.net/cgit.cgi/foobar/commit/?h=branch-a&id=a6d74e055b0dcb3a2e16ccceab2670af6e57069d
Aaron Griffin wrote:
I dunno, I don't see this as a problem because it's just not the way my workflow works. I make heavy use of git (well, git svn) at work, on huge amounts of code, and never run into these issues.
I can certainly believe that git is very appropriate for certain workflows, and the more closely the way you want to work matches the git way, the happier you are. I can say that where I worked most recently, years and years of accumulated experience led to certain workflows for branching and merging that I don't think would have been easily adapted to the git way. But I could be wrong, in fact I'd love to be wrong, because it's obvious that lots of open source projects are adopting git and I expect I'll have to use git more and more in the future whether I like it or not. So I really hope that my issues with git are just misunderstandings and not something that will make my life very difficult when using it in the future.
I just tried the rename case and it worked perfectly fine.
http://code.phraktured.net/cgit.cgi/foobar/ branch-a was made off the first commit, all changes were done and committed, then I switched back to master, renamed a file I changed _twice_ in branch-a, switched back to branch-a and did a "git rebase master". You can see the results there. It even lists the new file name in the diffs
Attached are a few scripts to demonstrate what I'm talking about. First is losthistory.sh, that shows that after you rename a file on a branch and then merge that back to the master, you can't easily get the history of the file before the rename. That's a bummer and can make tracking the true history of a file difficult. Next is conflict.sh, that demonstrates that git gives conflicts if two contiguous lines of a file are modified on two separate branches. Introducing a newline between the lines allows git to merge properly. This has nothing to do with file renames, it's just something that bit me while I was composing some of these other scripts, and I thought it was interesting. Run 'conflict.sh' to see how the merge is properly handled, and then 'conflict.sh broken' to see how the merge is not properly handled if the modified lines don't have a newline between them. Unfortunate. Finally, there's mvconflict.sh. This is the exact same as conflict.sh except that it always has the newline in between the lines (so that we know that git ought to be able to merge properly), and it renames the file on the branch before modifying it. git cannot merge the file after it has been moved and modified on the branch, and modified but not moved on the master, although it should be able to because the changes are exactly the same as in conflict.sh (that did merge properly), except with a file rename in the middle. Perhaps rebase works better than merge when handling file renames, I don't know. Merging in Perforce is nice because you retain development history of files across branches; but I can see how this might be contrary to the git philosophy. After all, branches are generally local in git, and you lose all of your branch history when you rebase/merge your changes back into master for the purposes of pushing those changes to master in the origin git server anyway, especially if you use squash to collapse your history. I'd be happy to take further discussion off-list if people are getting tired of this. Thanks, Bryan
On Mon, Feb 23, 2009 at 4:42 PM, Bryan Ischo <bji-keyword-pacman.3644cb@www.ischo.com> wrote:
Aaron Griffin wrote:
I dunno, I don't see this as a problem because it's just not the way my workflow works. I make heavy use of git (well, git svn) at work, on huge amounts of code, and never run into these issues.
I can certainly believe that git is very appropriate for certain workflows, and the more closely the way you want to work matches the git way, the happier you are. I can say that where I worked most recently, years and years of accumulated experience led to certain workflows for branching and merging that I don't think would have been easily adapted to the git way. But I could be wrong, in fact I'd love to be wrong, because it's obvious that lots of open source projects are adopting git and I expect I'll have to use git more and more in the future whether I like it or not. So I really hope that my issues with git are just misunderstandings and not something that will make my life very difficult when using it in the future.
I just tried the rename case and it worked perfectly fine.
http://code.phraktured.net/cgit.cgi/foobar/ branch-a was made off the first commit, all changes were done and committed, then I switched back to master, renamed a file I changed _twice_ in branch-a, switched back to branch-a and did a "git rebase master". You can see the results there. It even lists the new file name in the diffs
Attached are a few scripts to demonstrate what I'm talking about.
First is losthistory.sh, that shows that after you rename a file on a branch and then merge that back to the master, you can't easily get the history of the file before the rename. That's a bummer and can make tracking the true history of a file difficult.
Next is conflict.sh, that demonstrates that git gives conflicts if two contiguous lines of a file are modified on two separate branches. Introducing a newline between the lines allows git to merge properly. This has nothing to do with file renames, it's just something that bit me while I was composing some of these other scripts, and I thought it was interesting. Run 'conflict.sh' to see how the merge is properly handled, and then 'conflict.sh broken' to see how the merge is not properly handled if the modified lines don't have a newline between them. Unfortunate.
Finally, there's mvconflict.sh. This is the exact same as conflict.sh except that it always has the newline in between the lines (so that we know that git ought to be able to merge properly), and it renames the file on the branch before modifying it. git cannot merge the file after it has been moved and modified on the branch, and modified but not moved on the master, although it should be able to because the changes are exactly the same as in conflict.sh (that did merge properly), except with a file rename in the middle.
Perhaps rebase works better than merge when handling file renames, I don't know. Merging in Perforce is nice because you retain development history of files across branches; but I can see how this might be contrary to the git philosophy. After all, branches are generally local in git, and you lose all of your branch history when you rebase/merge your changes back into master for the purposes of pushing those changes to master in the origin git server anyway, especially if you use squash to collapse your history.
I'd be happy to take further discussion off-list if people are getting tired of this.
I think mailman scrubbed the attachments... :( But I noticed something - are you using "merge" exclusively? That may be part of the issue here. Most of the time when I merge, say branch-a onto master, I checkout branch-a, rebase master, checkout master, merge branch-a. Even when cherry-picking commits, a rebase cleans up common commits properly. Perhaps that's part of the issue here - not using rebase
Aaron Griffin wrote:
On Mon, Feb 23, 2009 at 4:42 PM, Bryan Ischo <bji-keyword-pacman.3644cb@www.ischo.com> wrote:
Aaron Griffin wrote:
I dunno, I don't see this as a problem because it's just not the way my workflow works. I make heavy use of git (well, git svn) at work, on huge amounts of code, and never run into these issues.
I can certainly believe that git is very appropriate for certain workflows, and the more closely the way you want to work matches the git way, the happier you are. I can say that where I worked most recently, years and years of accumulated experience led to certain workflows for branching and merging that I don't think would have been easily adapted to the git way. But I could be wrong, in fact I'd love to be wrong, because it's obvious that lots of open source projects are adopting git and I expect I'll have to use git more and more in the future whether I like it or not. So I really hope that my issues with git are just misunderstandings and not something that will make my life very difficult when using it in the future.
I just tried the rename case and it worked perfectly fine.
http://code.phraktured.net/cgit.cgi/foobar/ branch-a was made off the first commit, all changes were done and committed, then I switched back to master, renamed a file I changed _twice_ in branch-a, switched back to branch-a and did a "git rebase master". You can see the results there. It even lists the new file name in the diffs
Attached are a few scripts to demonstrate what I'm talking about.
First is losthistory.sh, that shows that after you rename a file on a branch and then merge that back to the master, you can't easily get the history of the file before the rename. That's a bummer and can make tracking the true history of a file difficult.
Next is conflict.sh, that demonstrates that git gives conflicts if two contiguous lines of a file are modified on two separate branches. Introducing a newline between the lines allows git to merge properly. This has nothing to do with file renames, it's just something that bit me while I was composing some of these other scripts, and I thought it was interesting. Run 'conflict.sh' to see how the merge is properly handled, and then 'conflict.sh broken' to see how the merge is not properly handled if the modified lines don't have a newline between them. Unfortunate.
Finally, there's mvconflict.sh. This is the exact same as conflict.sh except that it always has the newline in between the lines (so that we know that git ought to be able to merge properly), and it renames the file on the branch before modifying it. git cannot merge the file after it has been moved and modified on the branch, and modified but not moved on the master, although it should be able to because the changes are exactly the same as in conflict.sh (that did merge properly), except with a file rename in the middle.
Perhaps rebase works better than merge when handling file renames, I don't know. Merging in Perforce is nice because you retain development history of files across branches; but I can see how this might be contrary to the git philosophy. After all, branches are generally local in git, and you lose all of your branch history when you rebase/merge your changes back into master for the purposes of pushing those changes to master in the origin git server anyway, especially if you use squash to collapse your history.
I'd be happy to take further discussion off-list if people are getting tired of this.
I think mailman scrubbed the attachments... :(
But I noticed something - are you using "merge" exclusively? That may be part of the issue here. Most of the time when I merge, say branch-a onto master, I checkout branch-a, rebase master, checkout master, merge branch-a. Even when cherry-picking commits, a rebase cleans up common commits properly. Perhaps that's part of the issue here - not using rebase
Yes, I use merge almost exclusively. I only use rebase to bring my changes that haven't been committed to the origin master up to the head of my local master branch, to ensure that they would continue to apply without changes to the master branch as it currently stands. I think it's clear that I am not entirely in tune with the zen of git yet, which is probably the cause of the majority of the problems I have had with it. I will start by trying to understand rebase much better, since it seems to be key to doing alot of things in git. I will append my scripts inline here. Thanks, Bryan --- #!/bin/sh -x mkdir losthistory cd losthistory git init echo "This is a file." > file git add file git commit -m "Added file" git checkout -b branch git mv file file2 git commit -m "Moved file to file2" echo "This is a file now named file2." > file2 git add file2 git commit -m "Modified file2" git checkout master git merge branch git log -M file2 --- #!/bin/sh -x mkdir conflict cd conflict git init echo "This is a fil." > file if [ -z "$1" ]; then echo >> file fi echo "It has two line." >> file git add file git commit -m "Added file" git checkout -b branch echo "This is a fil." > file if [ -z "$1" ]; then echo >> file fi echo "It has two lines." >> file git add file git commit -m "Fixed second line of file" git checkout master echo "This is a file." > file if [ -z "$1" ]; then echo >> file fi echo "It has two line." >> file git add file git commit -m "Fixed first line of file" git checkout branch git merge master --- #!/bin/sh -x mkdir mvconflict cd mvconflict git init echo "This is a fil." > file echo >> file echo "It has two line." >> file git add file git commit -m "Added file" git checkout -b branch git mv file file2 git commit -m "Renamed file -> file2" echo "This is a fil." > file2 echo >> file2 echo "It has two lines." >> file2 git add file2 git commit -m "Fixed second line of file2" git checkout master echo "This is a file." > file echo >> file echo "It has two line." >> file git add file git commit -m "Fixed first line of file" git checkout branch git merge master
On 24/02/2009, at 6:10 AM, Bryan Ischo wrote:
It's not the ability to modify a single file in two different places at once. It's the ability to keep changes logically separated by directory, in a persistent manner that doesn't require git commands to put changes away and bring them back, that I care about. I find it infinitely easier to keep track of what I am doing by persistently retaining directory contents than by having a single working view and everything else being stashed away to be retrieved later.
I apologise if I'm missing something, but what's the difference between "cd ../branch" and "git checkout branch"? The state of your "working directory" is changed. You still have only one view of the directory. You can obviously view files in the other directory, but that's also possible with git, albeit somewhat harder if using a file manager. There are many GUI front-ends that allow you to quickly look at other branches and commits. What's the between "ls project-root" and "git branch"? Both list the "branches", both allow you to switch to that branch (cd, git checkout). I really don't see the difference, besides a clean project directory, in git's case.
One example of where git stash is more cumbersome is if you've created new files but haven't added them to the index yet. You have to add them to the index before you can stash. Now this is not a huge deal, but it does require more work to prep your tree for a stash than simply cd'ing out to another branch directory would take. There may be other cases where more work is involved in stashing (above and beyond having to actually run the git stash commands and maintain the list of stashes) than is involved in using locally stored branches, but I haven't used git stash enough to discover them. It would not surprise me to learn that there are lots of subtle details to be aware of when using git stash.
This is a bit of an annoyance, but it probably has more to do with workflow and discipline rather than git. You could leave that file there without tracking it at all, as long as the same file doesn't exist in another branch. However, this would be bad, since it's not "attached" to any branch and could get confusing. Before `git stash` came about, people just used `git commit -a -m "WIP something"`, which is pretty much all `git stash` does, except in a different... ref list I suppose. In this edge-case it's a bit more work to change to a different branch, but I think it only encourages to use the SCM properly.
Parallel branch directories have an advantage over git's branch views whenever you need to compare the contents of branches.
False. As mentioned earlier there are GUI tools which make this simple. If you don't like GUIs, you can use the command line equivalents (most tools execute git commands anyway). I don't know what these are since I've never had the need to compare two branches beyond `git diff`.
Maybe it's because I'm an emacs [...] [and] keeping track of [...] what sequence of [...] commands I need [...] is just more mental effort than I want to undertake.
*cheap shot alert* You use emacs, yet remembering commands is too much of an effort? I know I twisted your words a lot, and I'm not hating on emacs, but you have to admit that that is somewhat hypocritical.
I find it so much easier to just leave a branch subdirectory and when I return to it later, it is guaranteed to be exactly as it was when I left, without any effort on my part. If I am working on 4 or 5 bugs in parallel (which I have certainly done at work, where working on just 1 or 2 bugs at once would be inefficient because of the downtime associated with building each tree) I can't even imagine using git stashes to sanely keep track of everything.
This is exactly what branches are for. The exact same thing can be said for git branches. It's guaranteed to be exactly as it was when you switched to another branch. `git stash` should only be used when something is not ready to be committed, but you _urgently_ need to do something else, like a bug fix on the maintenance branch.
- Lack of rename tracking. Yeah, I know, git claims that it can do it after the fact when examining change histories but I've tried various scenarios and it just doesn't work very well, and even when it does, requires stupidly complex options to git commands to enable git to discover renames in the history correctly
I can't think of a situation where the file name is relevant. Even when renaming...
The problem comes when someone, in a branch, renames a file, and then tries to merge their changes into another branch in which the file was not renamed.
This would only be a problem if the file was not only renamed, but also _changed_, and significantly at that. In this case git would only see that, say, 60% of the file content was moved. I'm not sure how merging would work, since I have never worked on a branch when a file was moved (and changed) in another.
Unless file renames are tracked, the merge becomes very difficult.
Not at all. If git sees that the file content was _moved_ (not changed), it should be able to figure that out easily. Again, I haven't actually done this, but I don't see why it wouldn't work. I would suggest asking about this on #git (or the git ML). If it is indeed a problem then file a bug. I'm sure Linus would be happy to comment on it ;).
Refactoring a subsystem on a 'workbranch' is something that is done sometimes on large projects, and with git, I would expect that to be basically impossible to do sanely. Even if git's 'detect renames while examining history' technique did work, it still makes renames cumbersome, because you can't rename a file and change its contents at the same time or else git has almost no chance of detecting the rename via history. And if you can't change a file and rename it at the same time, then you can't, for example, properly rename a Java class, because the class name and file name have to be the same.
Why not? If you change the file contents and rename it, then obviously you'd also change the class name. Why else would you rename it?
It just shouldn't be that hard.
Why not? I can't imagine other SCMs doing this any better. If a file contents changes drastically, it doesn't matter if the name of the file is tracked. The name of the file is irrelevant. A merge conflict would arise even if the file was never renamed. I don't mean to contradict everything you say, it's just that I haven't had the same experience with git as you. Using git has been amazing. It does everything I want, it's sophisticated, it merges code well, and it has some very powerful features (like rebase). By the way, Mercurial seems faster than Bazaar (though I haven't used either much), and both are written in Python. Mercurial might not be pure python though, I am unsure.
I really don't mind the talk about workflow (I have improved my weak git-fu), but following this list has been difficult in the last few days because of lack of subject line changes. Please change subject lines when appropriate. Also, there are some fairly long responses. I have quite a low "tl;dr" threshold, so please just get your point over succinctly and save us all some time. Allan
On Mon, Feb 23, 2009 at 9:42 PM, Allan McRae <allan@archlinux.org> wrote:
I really don't mind the talk about workflow (I have improved my weak git-fu), but following this list has been difficult in the last few days because of lack of subject line changes. Please change subject lines when appropriate.
My fault on this, I'm usually pretty good about this, but thanks for bringing it up.
Also, there are some fairly long responses. I have quite a low "tl;dr" threshold, so please just get your point over succinctly and save us all some time.
And if you can't be succinct, please branch it off to another thread so we stay as on topic as possible. -Dan
On Mon, Feb 23, 2009 at 11:22 PM, Dan McGee <dpmcgee@gmail.com> wrote:
On Mon, Feb 23, 2009 at 9:42 PM, Allan McRae <allan@archlinux.org> wrote:
I really don't mind the talk about workflow (I have improved my weak git-fu), but following this list has been difficult in the last few days because of lack of subject line changes. Please change subject lines when appropriate.
My fault on this, I'm usually pretty good about this, but thanks for bringing it up.
I'm never good at it. Feel free to call me out for being stupid - I sometimes forget I'm changing topics :)
Thank you for your excellent comments, Sebastian. I hope I can do them justice with my responses, inlined below ... Sebastian Nowicki wrote:
On 24/02/2009, at 6:10 AM, Bryan Ischo wrote:
It's not the ability to modify a single file in two different places at once. It's the ability to keep changes logically separated by directory, in a persistent manner that doesn't require git commands to put changes away and bring them back, that I care about. I find it infinitely easier to keep track of what I am doing by persistently retaining directory contents than by having a single working view and everything else being stashed away to be retrieved later.
I apologise if I'm missing something, but what's the difference between "cd ../branch" and "git checkout branch"? The state of your "working directory" is changed. You still have only one view of the directory. You can obviously view files in the other directory, but that's also possible with git, albeit somewhat harder if using a file manager. There are many GUI front-ends that allow you to quickly look at other branches and commits. What's the between "ls project-root" and "git branch"? Both list the "branches", both allow you to switch to that branch (cd, git checkout). I really don't see the difference, besides a clean project directory, in git's case.
The difference is subtle. Obviously you can work in both ways, and apparently, many people on this list like using git commands instead of 'normal' filesystem navigation for visiting files in their branches. I can think of a few ways to expand upon my thoughts about the 'git way' versus the 'Perforce way': An analogy: using git is kind of like keeping every directory in your home directory in a separate tar file, except for one untarred working directory. Whenever you want to cd into a new directory, you have to tar up the directory you were just in, and then untar the directory you want to cd into. Only the current working directory (and everything under it) can be untarred, everything else has to be tarred up if you're not in it. Would you like to maintain your home directory this way? It sounds like a major pain to me. Although having to issue tar and untar commands constantly while you are working with files in your home directory doesn't sound all that bad, in practice, it would be so much less convenient than if all of your files were untarred all the time and you could just look through them without having to manage the tar files. I suppose if someone has only ever used a system where they had to constantly tar up and untar directories, they wouldn't think anything of it (and would think that a command like 'cd-stash' which tars up your cwd and untars some other tarred directory and cd's into it would be really cool), but if you've had the 'freedom' of just working with your files without such encumbrances, you'll really hate having to do it. An example of what I can do with parallel branches: if my branch 'new' and 'old' were stored in two separate subdirectories, then I could grep through all of the files in both branches with one command and see collated results; or could diff only files in which a given identifier appeared only in a file on one branch but not the corresponding file on another. Another example is the compiled results of each tree, as I mentioned before, which I can see and compare in place if my branches are in different subtrees, but which requires extra copying around of files and other management if I am using git. Another problem with git: I have to constantly rebuild stuff when I stash and unstash because my build directory doesn't stash. It's interesting that you note that viewing files in other branches with git is harder if you are using a file manager. That's exactly the point I am trying to make: file managers and other tools (scripting languages, diffing tools, text searching and processing tools, etc) all work based on the standard Unix paradigm of "everything is a file". Git works on a paradigm of "everything in your current branch is a file, everything else is accessible only as the output of a complex git command". I'd rather use a paradigm that thousands of tools already depend on, than the special case paradigm that is git. A few more points: I don't think that "many GUI front-ends" being available to help me manage my branches is better than a system that doesn't need any GUI front-ends to make the process palatable. And, I'm not sure why what git does is any 'cleaner' than keeping branches in separate directories. If anything, git seems messier to me because some files get changed in-place as you switch branches in git, and some files are ignored and left as they are (those that aren't actually tracked by git), and distinguishing between the two types requires git commands and lots of mental notes.
Parallel branch directories have an advantage over git's branch views whenever you need to compare the contents of branches.
False. As mentioned earlier there are GUI tools which make this simple. If you don't like GUIs, you can use the command line equivalents (most tools execute git commands anyway). I don't know what these are since I've never had the need to compare two branches beyond `git diff`.
Well, I think that the fact that you have to qualify your statement by saying that it's easy if you use special GUIs, and otherwise doable with command line equivalents, exactly makes my point. There are many more ways to compare branches than just 'git diff'. You can compare the result of building both branches, you can do a grep over multiple branches at once to find identifiers, you can count line numbers for entire branches if you like to see how much bigger your code base is in one branch than another ... these things can all be done with git too, but you have to run many git commands to get the views of the branches that you need when you need them, whereas if they all live in separate subdirectories, there are no commands to run at all to get the files ... they're just there.
Maybe it's because I'm an emacs [...] [and] keeping track of [...] what sequence of [...] commands I need [...] is just more mental effort than I want to undertake.
*cheap shot alert* You use emacs, yet remembering commands is too much of an effort? I know I twisted your words a lot, and I'm not hating on emacs, but you have to admit that that is somewhat hypocritical.
It wasn't meant to be hypocritical. I was trying to allude to the fact that when using vi, you have to remember much more state about what you are doing (what mode am I in? insert mode? delete mode? what file am I working on? what line am I on? etc etc) than with emacs; I think this is one of the fundamental differences between vi and emacs. I could be wrong though, I haven't used vi extensively, just enough to make minor edits to files on the way to getting emacs installed :) But assuming that this is true, then it was just the fact that vi users are used to keeping more state about what they are doing in their head that makes git seem natural. Perhaps I should have said 'ed' instead of 'vi' ... Note that I'm not talking about remembering what commands do what (certainly emacs has tons of commands to remember), I'm talking about keeping track of working state as you are using the tool. git seems to require keeping a mental model of branches that you can't even "see" because they aren't in your filesystem anywhere.
I find it so much easier to just leave a branch subdirectory and when I return to it later, it is guaranteed to be exactly as it was when I left, without any effort on my part. If I am working on 4 or 5 bugs in parallel (which I have certainly done at work, where working on just 1 or 2 bugs at once would be inefficient because of the downtime associated with building each tree) I can't even imagine using git stashes to sanely keep track of everything.
This is exactly what branches are for. The exact same thing can be said for git branches. It's guaranteed to be exactly as it was when you switched to another branch. `git stash` should only be used when something is not ready to be committed, but you _urgently_ need to do something else, like a bug fix on the maintenance branch.
Except that not only am I getting confused about the state of my branches as I commit partially complete changes to them for the purpose of saving state as I switch between branches, the tools that I use are getting confused as well. I may have editors and other tools open for files whose contents suddenly change when I git checkout to a different branch. For many tools, this is not a big deal, but I think it illustrates the subtle problems that such an approach introduces. And since I encapsulate part of the state of "what I'm doing" in the state of the tools that I am using, confused state in those tools can often confuse me as well. With git, I can't switch to another branch unless I either a) commit the changes (which I may not be ready to commit yet), or b) stash the changes. Committing or stashing take extra work on my part. Why should I have to do this work?
- Lack of rename tracking. Yeah, I know, git claims that it can do it after the fact when examining change histories but I've tried various scenarios and it just doesn't work very well, and even when it does, requires stupidly complex options to git commands to enable git to discover renames in the history correctly
I can't think of a situation where the file name is relevant. Even when renaming...
Do some google searches. File renaming in version control systems is a big deal, and for good reason.
The problem comes when someone, in a branch, renames a file, and then tries to merge their changes into another branch in which the file was not renamed.
This would only be a problem if the file was not only renamed, but also _changed_, and significantly at that. In this case git would only see that, say, 60% of the file content was moved. I'm not sure how merging would work, since I have never worked on a branch when a file was moved (and changed) in another.
Yes; it's called refactoring. On a well managed project it doesn't happen often, but it does happen. Reorganization of subtrees of code is something that source control systems should support well. It's the merging after such reorganization that tools that don't track renames have problems with. For examples of git failing in this, take a look at the simple scripts I sent out to the list earlier today.
Unless file renames are tracked, the merge becomes very difficult.
Not at all. If git sees that the file content was _moved_ (not changed), it should be able to figure that out easily. Again, I haven't actually done this, but I don't see why it wouldn't work. I would suggest asking about this on #git (or the git ML). If it is indeed a problem then file a bug. I'm sure Linus would be happy to comment on it ;).
It's not just moving. It's moving and changing that git has a problem with.
Refactoring a subsystem on a 'workbranch' is something that is done sometimes on large projects, and with git, I would expect that to be basically impossible to do sanely. Even if git's 'detect renames while examining history' technique did work, it still makes renames cumbersome, because you can't rename a file and change its contents at the same time or else git has almost no chance of detecting the rename via history. And if you can't change a file and rename it at the same time, then you can't, for example, properly rename a Java class, because the class name and file name have to be the same.
Why not? If you change the file contents and rename it, then obviously you'd also change the class name. Why else would you rename it?
Git doesn't allow you to rename and change contents of a file at the same time: $ git mv file file2 $ echo "changed file" > file2 $ git status # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # renamed: file -> file2 # # Changed but not updated: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # modified: file2 # If I 'git commit' it will take the rename of file to file2, but not the modification of file2. If I try to add file2 before committing, git status now shows: # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # deleted: file # new file: file2 If you check this in, git will not be able to merge changes to file2 into a branch taken before this change.
It just shouldn't be that hard.
Why not? I can't imagine other SCMs doing this any better. If a file contents changes drastically, it doesn't matter if the name of the file is tracked. The name of the file is irrelevant. A merge conflict would arise even if the file was never renamed.
Perforce does it better. It is certainly possible to: * Rename bunches of files on a branch as part of a code refactoring effort and change parts of those files to match (such as class names, etc) * Make bug fixes to the original files in a different branch * Merge those changes together on either branch in a way that makes sense and doesn't produce conflicts (assuming that the individual changes were not conflicting, which is often the case when one branch is doing minor bugfixes and the other is doing more structural work)
I don't mean to contradict everything you say, it's just that I haven't had the same experience with git as you. Using git has been amazing. It does everything I want, it's sophisticated, it merges code well, and it has some very powerful features (like rebase).
I'm glad you like git so much, alot of people do. I'm not saying I don't like git, I'm just saying that there are a few things that I think suck about git. That's how this discussion got started. But alot of people defend git with great vigor if anything critical is said of it, and I don't understand the fervor. My impression of git is that it feels very much like what its history suggests that it is: a tool for managing patches that grew into a source control system. For better or worse, git feels 'messy' to me, like it wasn't thought out ahead of time but kind of organically grew as people realized that certain basic features could be twisted this way or that way to add the equivalent of standard source control functionality. Git has dozens of commands, each with dozens of subtle and tricky options; that seems like needless complexity to me. That's just my impression, take it for what it's worth, which is not much.
By the way, Mercurial seems faster than Bazaar (though I haven't used either much), and both are written in Python. Mercurial might not be pure python though, I am unsure.
I really like what I read on the bazaar web pages; it feels more coherently designed than git, and much simpler to use. But it worries me that it's had significant performance problems on larger projects. Thanks, Bryan
On Mon, Feb 23, 2009 at 9:30 PM, Sebastian Nowicki <sebnow@gmail.com> wrote:
On 24/02/2009, at 6:10 AM, Bryan Ischo wrote:
It's not the ability to modify a single file in two different places at once. It's the ability to keep changes logically separated by directory, in a persistent manner that doesn't require git commands to put changes away and bring them back, that I care about. I find it infinitely easier to keep track of what I am doing by persistently retaining directory contents than by having a single working view and everything else being stashed away to be retrieved later.
I apologise if I'm missing something, but what's the difference between "cd ../branch" and "git checkout branch"? The state of your "working directory" is changed. You still have only one view of the directory. You can obviously view files in the other directory, but that's also possible with git, albeit somewhat harder if using a file manager. There are many GUI front-ends that allow you to quickly look at other branches and commits. What's the between "ls project-root" and "git branch"? Both list the "branches", both allow you to switch to that branch (cd, git checkout). I really don't see the difference, besides a clean project directory, in git's case.
I'll add another tip here- there is nothing inherently wrong with having multiple workign directories if you really want them. git clone is a cheap operation, and will give you exactly what you want. I have 'pacman' and 'pacman-maint' directories, where the pacman-maint one is simply a clone of pacman so I can easily do things on the maint branch without messing with my WIP on the current master branch. I then simply push the maint ref back into the master local repo as necessary. -Dan
Dan McGee wrote:
I never use git-merge when doing my own work, btw- I'm really not sure that makes workflow easy at all, as I tend to cherrypick things around on multiple working branches if I want to move patches.
So while we are getting git tutorials, do you mind giving an example command that does this. I always end up in a mess when trying to do that... Allan
On Sun, Feb 22, 2009 at 10:14 PM, Allan McRae <allan@archlinux.org> wrote:
Dan McGee wrote:
I never use git-merge when doing my own work, btw- I'm really not sure that makes workflow easy at all, as I tend to cherrypick things around on multiple working branches if I want to move patches.
So while we are getting git tutorials, do you mind giving an example command that does this. I always end up in a mess when trying to do that...
OK. So I'm busy reintegrating some of your guys' stuff into [master], when I see a problem that I need to fix. I go ahead and fix it, make my own commit...and then realize this fix should be on [maint]. git log, look for the sha1 commit ID of the commit I want to move git co maint git chp <sha1> profit! co? chp? what are those, you ask? git aliases are awesome: $ git config --list alias.co=checkout alias.chp=cherry-pick alias.b=branch alias.m=merge alias.rf=checkout HEAD I think it is something like "git config alias.co checkout". I'd then go back and remove that commit from [master]. If it was still the last thing I did, I'd "git reset --hard HEAD^". If it was further back, rebase -i to the rescue and just delete the line. -Dan
On Sun, Feb 22, 2009 at 10:20 PM, Dan McGee <dpmcgee@gmail.com> wrote:
On Sun, Feb 22, 2009 at 10:14 PM, Allan McRae <allan@archlinux.org> wrote:
Dan McGee wrote:
I never use git-merge when doing my own work, btw- I'm really not sure that makes workflow easy at all, as I tend to cherrypick things around on multiple working branches if I want to move patches.
So while we are getting git tutorials, do you mind giving an example command that does this. I always end up in a mess when trying to do that...
OK. So I'm busy reintegrating some of your guys' stuff into [master], when I see a problem that I need to fix. I go ahead and fix it, make my own commit...and then realize this fix should be on [maint].
git log, look for the sha1 commit ID of the commit I want to move git co maint git chp <sha1> profit!
co? chp? what are those, you ask? git aliases are awesome:
$ git config --list alias.co=checkout alias.chp=cherry-pick alias.b=branch alias.m=merge alias.rf=checkout HEAD
I think it is something like "git config alias.co checkout".
I'd then go back and remove that commit from [master]. If it was still the last thing I did, I'd "git reset --hard HEAD^". If it was further back, rebase -i to the rescue and just delete the line.
So when you cherry-pick, you actually then remove the commit from the original branch and rebase? I never thought of it that way, that actually cleans up some confusion I had with cherry-pick to begin with.
On Mon, Feb 23, 2009 at 9:55 AM, Aaron Griffin <aaronmgriffin@gmail.com> wrote:
On Sun, Feb 22, 2009 at 10:20 PM, Dan McGee <dpmcgee@gmail.com> wrote:
On Sun, Feb 22, 2009 at 10:14 PM, Allan McRae <allan@archlinux.org> wrote:
Dan McGee wrote:
I never use git-merge when doing my own work, btw- I'm really not sure that makes workflow easy at all, as I tend to cherrypick things around on multiple working branches if I want to move patches.
So while we are getting git tutorials, do you mind giving an example command that does this. I always end up in a mess when trying to do that...
OK. So I'm busy reintegrating some of your guys' stuff into [master], when I see a problem that I need to fix. I go ahead and fix it, make my own commit...and then realize this fix should be on [maint].
git log, look for the sha1 commit ID of the commit I want to move git co maint git chp <sha1> profit!
co? chp? what are those, you ask? git aliases are awesome:
$ git config --list alias.co=checkout alias.chp=cherry-pick alias.b=branch alias.m=merge alias.rf=checkout HEAD
I think it is something like "git config alias.co checkout".
I'd then go back and remove that commit from [master]. If it was still the last thing I did, I'd "git reset --hard HEAD^". If it was further back, rebase -i to the rescue and just delete the line.
So when you cherry-pick, you actually then remove the commit from the original branch and rebase? I never thought of it that way, that actually cleans up some confusion I had with cherry-pick to begin with.
Something like that, yes. Of course, rewriting history shouldn't be done unless the branches are private to you (or you haven't shared/pushed them out yet). cherry-pick is definitely a super-easy way to assemble a new branch to test small pieces of things, or to throw away some commits you weren't happy with. -Dan
On Sun, Feb 22, 2009 at 4:25 AM, Bryan Ischo <bji-keyword-pacman.3644cb@www.ischo.com> wrote:
From: Bryan Ischo <bryan@ischo.com>
Enabled a new prompt to ask the user if they'd like to remove unresolvable packages from the transaction rather than failing it.
Many pactest tests that used to fail not return success codes, because pacman now issues a prompt allowing the user to cancel rather than failing many transactions, and the pactest scripts always choose to cancel with no error rather than failing. The only net effect is that the return status of pacman is now 0 in cases where it used to be nonzero.
Signed-off-by: Bryan Ischo <bryan@ischo.com> --- lib/libalpm/alpm.h | 3 ++- lib/libalpm/deps.c | 6 +++--- lib/libalpm/sync.c | 23 ++++++++++++++++++----- pactest/tests/provision020.py | 2 +- pactest/tests/provision022.py | 2 +- pactest/tests/sync1008.py | 2 +- pactest/tests/sync300.py | 2 +- src/pacman/callback.c | 16 ++++++++++++++++ 8 files changed, 43 insertions(+), 13 deletions(-)
diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index 7b7ca4e..3836d60 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -371,7 +371,8 @@ typedef enum _pmtransconv_t { PM_TRANS_CONV_REPLACE_PKG = 0x02, PM_TRANS_CONV_CONFLICT_PKG = 0x04, PM_TRANS_CONV_CORRUPTED_PKG = 0x08, - PM_TRANS_CONV_LOCAL_NEWER = 0x10 + PM_TRANS_CONV_LOCAL_NEWER = 0x10, + PM_TRANS_CONV_REMOVE_PKGS = 0x20, } pmtransconv_t;
/* Transaction Progress */ diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c index 41d2a83..ebcd18d 100644 --- a/lib/libalpm/deps.c +++ b/lib/libalpm/deps.c @@ -531,8 +531,8 @@ pmpkg_t *_alpm_resolvedep(pmdepend_t *dep, alpm_list_t *dbs, alpm_list_t *exclud !_alpm_pkg_find(excluding, pkg->name)) { if(_alpm_pkg_should_ignore(pkg)) { int install; - QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, pkg, - tpkg, NULL, &install); + QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, + pkg, tpkg, NULL, &install); if(!install) { continue; } @@ -609,7 +609,7 @@ int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *pkg, if(!spkg) { pm_errno = PM_ERR_UNSATISFIED_DEPS; char *missdepstring = alpm_dep_compute_string(missdep); - _alpm_log(PM_LOG_ERROR, _("cannot resolve \"%s\", a dependency of \"%s\"\n"), + _alpm_log(PM_LOG_WARNING, _("cannot resolve \"%s\", a dependency of \"%s\"\n"), missdepstring, tpkg->name); free(missdepstring); if(data) { diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c index 5e5ca92..ea903f4 100644 --- a/lib/libalpm/sync.c +++ b/lib/libalpm/sync.c @@ -442,12 +442,25 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync dependencies not already on the list */ }
- /* If there were unresolvable top-level packages, fail the - transaction. */ + /* If there were unresolvable top-level packages, prompt the user to + see if they'd like to ignore them rather than failing the sync */ if(unresolvable != NULL) { - /* pm_errno is set by resolvedeps */ - ret = -1; - goto cleanup; + int remove_unresolvable = 0; + QUESTION(handle->trans, PM_TRANS_CONV_REMOVE_PKGS, unresolvable, NULL, NULL, &remove_unresolvable); + if (remove_unresolvable) { + /* User wants to remove the unresolvable packages from the + transaction, so simply drop the unresolvable list. The + packages will be removed from the actual transaction when + the transaction packages are replaced with a + dependency-reordered list below */ + alpm_list_free(unresolvable); + unresolvable = NULL; + } + else { + /* pm_errno is set by resolvedeps */ + ret = -1; + goto cleanup; + } }
/* Add all packages which were "pulled" (i.e. weren't already in the diff --git a/pactest/tests/provision020.py b/pactest/tests/provision020.py index 7cb0a01..c9c0ac3 100644 --- a/pactest/tests/provision020.py +++ b/pactest/tests/provision020.py @@ -10,6 +10,6 @@
self.args = "-S %s" % p.name
-self.addrule("PACMAN_RETCODE=1") +self.addrule("PACMAN_RETCODE=0") self.addrule("!PKG_EXIST=pkg1") self.addrule("PKG_EXIST=pkg2") diff --git a/pactest/tests/provision022.py b/pactest/tests/provision022.py index 4883d42..190a8b6 100644 --- a/pactest/tests/provision022.py +++ b/pactest/tests/provision022.py @@ -10,6 +10,6 @@
self.args = "-S %s" % p.name
-self.addrule("PACMAN_RETCODE=1") +self.addrule("PACMAN_RETCODE=0") self.addrule("!PKG_EXIST=pkg1") self.addrule("PKG_EXIST=pkg2") diff --git a/pactest/tests/sync1008.py b/pactest/tests/sync1008.py index a606459..90c61df 100644 --- a/pactest/tests/sync1008.py +++ b/pactest/tests/sync1008.py @@ -14,6 +14,6 @@
self.args = "-S pkg"
-self.addrule("PACMAN_RETCODE=1") +self.addrule("PACMAN_RETCODE=0") self.addrule("!PKG_EXIST=pkg") self.addrule("!PKG_EXIST=cpkg") diff --git a/pactest/tests/sync300.py b/pactest/tests/sync300.py index 31b520a..36d6758 100644 --- a/pactest/tests/sync300.py +++ b/pactest/tests/sync300.py @@ -9,6 +9,6 @@
self.args = "-S %s" % sp1.name
-self.addrule("PACMAN_RETCODE=1") +self.addrule("PACMAN_RETCODE=0") self.addrule("!PKG_EXIST=pkg1") self.addrule("!PKG_EXIST=pkg2") diff --git a/src/pacman/callback.c b/src/pacman/callback.c index 6e7930c..d6b5b01 100644 --- a/src/pacman/callback.c +++ b/src/pacman/callback.c @@ -270,6 +270,22 @@ void cb_trans_conv(pmtransconv_t event, void *data1, void *data2, (char *)data2, (char *)data2); break; + case PM_TRANS_CONV_REMOVE_PKGS: + { + alpm_list_t *unresolved = (alpm_list_t *) data1; + alpm_list_t *namelist = NULL, *i; + for (i = unresolved; i; i = i->next) { + namelist = alpm_list_add(namelist, + (char *) alpm_pkg_get_name(i->data)); + } + printf(":: the following package(s) cannot be upgraded due to " + "unresolvable dependencies:\n"); + list_display(" ", namelist); + *response = yesno(_("\nDo you want to skip the above " + "package(s) for this upgrade?")); + alpm_list_free(namelist); + } + break;
You have a ton of tab/space issues in here, btw. I cleaned it up, but please be more careful next time.
case PM_TRANS_CONV_LOCAL_NEWER: if(!config->op_s_downloadonly) { *response = yesno(_(":: %s-%s: local version is newer. Upgrade anyway?"), -- 1.6.1
_______________________________________________ pacman-dev mailing list pacman-dev@archlinux.org http://www.archlinux.org/mailman/listinfo/pacman-dev
Dan McGee wrote:
You have a ton of tab/space issues in here, btw. I cleaned it up, but please be more careful next time.
Sigh. I will try to do better next time. Thanks, Bryan
participants (7)
-
Aaron Griffin
-
Allan McRae
-
Bryan Ischo
-
Dan McGee
-
Loui Chang
-
Sebastian Nowicki
-
Xavier