aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Linus Torvalds <torvalds@linux-foundation.org>2014-04-14 14:33:46 -0700
committerGravatar Dirk Hohndel <dirk@hohndel.org>2014-04-14 16:07:59 -0700
commita3aacfc6c2cbeccb81e18d6906fcc47cf01456a0 (patch)
treee5d5554cfd5883fbcf650e6a1bb041e1c8575ed9
parent7e1d8724c5e9800ade5590ff96d8290196755036 (diff)
downloadsubsurface-a3aacfc6c2cbeccb81e18d6906fcc47cf01456a0.tar.gz
git-save: improve commit authorship data
We used to always just commit as "subsurface@hohndel.org" 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 <torvalds@linux-foundation.org> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
-rw-r--r--dive.h6
-rw-r--r--linux.c23
-rw-r--r--macos.c3
-rw-r--r--save-git.c23
-rw-r--r--windows.c3
5 files changed, 56 insertions, 2 deletions
diff --git a/dive.h b/dive.h
index 89497b75a..62d57d6cc 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 ea0170dc8..8c79a3f2d 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) {
+ 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 19ce9e89d..25d6fd73f 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 2e8b608f8..76175a197 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 = "subsurace@hohndel.org"
+ };
+
+ 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", "subsurface@hohndel.org"))
+ 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 5a7707108..fbc8788a0 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];