From: Linus Torvalds <[email protected]> Date: Mon, 14 Apr 2014 14:33:46 -0700 Subject: [PATCH] git-save: improve commit authorship data
We used to always just commit as "[email protected]" because libgit-19 doesn't have the interfaces to do user name lookup. This does better if you have libgit-20, using "git_signature_default()" to get the actual user that does the saving. Signed-off-by: Linus Torvalds <[email protected]> --- This tries to use "git_signature_default()" to get user information for the commit authorship, but if libgit2 is too old, it falls back on creating the data by hand like it used to. But even then we try to actually get a real user name and fake email (really just user@hostname, not a real email). However, we do the real user name only on Linux. I assume the same getpwuid() approach would work on OSX, but Windows does its own thing. However, at least Dirk seems to compile current libgit2 for the OSX and Windows binaries, so it simply doesn't matter. On at least Fedora, the distro libgit2 is still 0.19 that doesn't have the new interfaces. dive.h | 6 ++++++ linux.c | 23 +++++++++++++++++++++++ macos.c | 3 +++ save-git.c | 23 +++++++++++++++++++++-- windows.c | 3 +++ 5 files changed, 56 insertions(+), 2 deletions(-) diff --git a/dive.h b/dive.h index 89497b75a057..62d57d6ccd59 100644 --- a/dive.h +++ b/dive.h @@ -714,6 +714,12 @@ extern const char *saved_git_id; extern void clear_git_id(void); extern void set_git_id(const struct git_oid *); +struct user_info { + const char *name; + const char *email; +}; + +extern void subsurface_user_info(struct user_info *); extern int subsurface_rename(const char *path, const char *newpath); extern int subsurface_open(const char *path, int oflags, mode_t mode); extern FILE *subsurface_fopen(const char *path, const char *mode); diff --git a/linux.c b/linux.c index ea0170dc89f8..03d0bfbf9670 100644 --- a/linux.c +++ b/linux.c @@ -2,16 +2,39 @@ /* implements Linux specific functions */ #include "dive.h" #include "display.h" +#include "membuffer.h" #include <string.h> #include <sys/types.h> #include <dirent.h> #include <fnmatch.h> #include <stdio.h> #include <fcntl.h> +#include <unistd.h> +#include <pwd.h> const char system_divelist_default_font[] = "Sans"; const int system_divelist_default_font_size = 8; +void subsurface_user_info(struct user_info *user) +{ + struct passwd *pwd = getpwuid(getuid()); + const char *username = getenv("USER"); + + if (pwd) { + if (pwd->pw_gecos && *pwd->pw_gecos) + user->name = pwd->pw_gecos; + if (!username) + username = pwd->pw_name; + } + if (username && *username) { + const char hostname[64]; + struct membuffer mb = { 0 }; + gethostname(hostname, sizeof(hostname)); + put_format(&mb, "%s@%s", username, hostname); + user->email = mb_cstring(&mb); + } +} + const char *system_default_filename(void) { const char *home, *user; diff --git a/macos.c b/macos.c index 19ce9e89dcd8..25d6fd73f373 100644 --- a/macos.c +++ b/macos.c @@ -13,6 +13,9 @@ #include <fcntl.h> #include <dirent.h> +void subsurface_user_info(struct user_info *info) +{ /* Nothing, let's use libgit2-20 on MacOS */ } + /* macos defines CFSTR to create a CFString object from a constant, * but no similar macros if a C string variable is supposed to be * the argument. We add this here (hardcoding the default allocator diff --git a/save-git.c b/save-git.c index 2e8b608f8160..76175a1974d5 100644 --- a/save-git.c +++ b/save-git.c @@ -815,6 +815,24 @@ static int update_git_checkout(git_repository *repo, git_object *parent, git_tre return git_checkout_tree(repo, (git_object *) tree, &opts); } +static int get_authorship(git_repository *repo, git_signature **authorp) +{ +#if LIBGIT2_VER_MAJOR || LIBGIT2_VER_MINOR >= 20 + return git_signature_default(authorp, repo); +#else + /* Default name information, with potential OS overrides */ + struct user_info user = { + .name = "Subsurface", + .email = "[email protected]" + }; + + subsurface_user_info(&user); + + /* git_signature_default() is too recent */ + return git_signature_now(authorp, user.name, user.email); +#endif +} + static int create_new_commit(git_repository *repo, const char *branch, git_oid *tree_id) { int ret; @@ -853,8 +871,7 @@ static int create_new_commit(git_repository *repo, const char *branch, git_oid * if (git_tree_lookup(&tree, repo, tree_id)) return report_error("Could not look up newly created tree"); - /* git_signature_default() is too recent */ - if (git_signature_now(&author, "Subsurface", "[email protected]")) + if (get_authorship(repo, &author)) return report_error("No user name configuration in git repo"); /* If the parent commit has the same tree ID, do not create a new commit */ @@ -897,6 +914,8 @@ static int create_new_commit(git_repository *repo, const char *branch, git_oid * return report_error("Failed to update branch '%s'", branch); set_git_id(&commit_id); + git_signature_free(author); + return 0; } diff --git a/windows.c b/windows.c index 5a7707108877..fbc8788a00b9 100644 --- a/windows.c +++ b/windows.c @@ -14,6 +14,9 @@ const char system_divelist_default_font[] = "Sans"; const int system_divelist_default_font_size = 8; +void subsurface_user(struct user_info *user) +{ /* Encourage use of at least libgit2-0.20 */ } + const char *system_default_filename(void) { char datapath[MAX_PATH]; -- 1.9.0 _______________________________________________ subsurface mailing list [email protected] http://lists.hohndel.org/cgi-bin/mailman/listinfo/subsurface
