From 1489dc4fd85172be1604b03666a5538ef8015bc7 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Fri, 15 Jun 2012 11:28:46 -0400 Subject: Disable 'Rename' if source is a collection member. For consistency with the Preferences window. We assume the display names are server-assigned and not user-assigned, at least not assigned through Evolution. --- modules/addressbook/e-book-shell-sidebar.c | 29 ++++++++++++++++++++++------- modules/addressbook/e-book-shell-sidebar.h | 5 +++-- modules/addressbook/e-book-shell-view.c | 13 +++++++++---- modules/calendar/e-cal-shell-sidebar.c | 28 ++++++++++++++++++++-------- modules/calendar/e-cal-shell-sidebar.h | 7 ++++--- modules/calendar/e-cal-shell-view.c | 13 +++++++++---- modules/calendar/e-memo-shell-sidebar.c | 28 ++++++++++++++++++++-------- modules/calendar/e-memo-shell-sidebar.h | 7 ++++--- modules/calendar/e-memo-shell-view.c | 13 +++++++++---- modules/calendar/e-task-shell-sidebar.c | 28 ++++++++++++++++++++-------- modules/calendar/e-task-shell-sidebar.h | 7 ++++--- modules/calendar/e-task-shell-view.c | 13 +++++++++---- 12 files changed, 133 insertions(+), 58 deletions(-) diff --git a/modules/addressbook/e-book-shell-sidebar.c b/modules/addressbook/e-book-shell-sidebar.c index b7f8b61ef9..2f2d9391c5 100644 --- a/modules/addressbook/e-book-shell-sidebar.c +++ b/modules/addressbook/e-book-shell-sidebar.c @@ -145,29 +145,44 @@ book_shell_sidebar_check_state (EShellSidebar *shell_sidebar) { EBookShellSidebar *book_shell_sidebar; ESourceSelector *selector; + ESourceRegistry *registry; ESource *source; - gboolean removable = FALSE; - gboolean writable = FALSE; + gboolean is_writable = FALSE; + gboolean is_removable = FALSE; + gboolean in_collection = FALSE; gboolean has_primary_source = FALSE; guint32 state = 0; book_shell_sidebar = E_BOOK_SHELL_SIDEBAR (shell_sidebar); selector = e_book_shell_sidebar_get_selector (book_shell_sidebar); source = e_source_selector_ref_primary_selection (selector); + registry = e_source_selector_get_registry (selector); if (source != NULL) { + ESource *collection; + has_primary_source = TRUE; - removable = e_source_get_removable (source); - writable = e_source_get_writable (source); + is_writable = e_source_get_writable (source); + is_removable = e_source_get_removable (source); + + collection = e_source_registry_find_extension ( + registry, source, E_SOURCE_EXTENSION_COLLECTION); + if (collection != NULL) { + in_collection = TRUE; + g_object_unref (collection); + } + g_object_unref (source); } if (has_primary_source) state |= E_BOOK_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE; - if (removable) - state |= E_BOOK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_REMOVABLE; - if (writable) + if (is_writable) state |= E_BOOK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_WRITABLE; + if (is_removable) + state |= E_BOOK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_REMOVABLE; + if (in_collection) + state |= E_BOOK_SHELL_SIDEBAR_PRIMARY_SOURCE_IN_COLLECTION; return state; } diff --git a/modules/addressbook/e-book-shell-sidebar.h b/modules/addressbook/e-book-shell-sidebar.h index 9e4d9ec015..9507681541 100644 --- a/modules/addressbook/e-book-shell-sidebar.h +++ b/modules/addressbook/e-book-shell-sidebar.h @@ -54,8 +54,9 @@ typedef struct _EBookShellSidebarPrivate EBookShellSidebarPrivate; enum { E_BOOK_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE = 1 << 0, - E_BOOK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_REMOVABLE = 1 << 1, - E_BOOK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_WRITABLE = 1 << 2 + E_BOOK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_WRITABLE = 1 << 1, + E_BOOK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_REMOVABLE = 1 << 2, + E_BOOK_SHELL_SIDEBAR_PRIMARY_SOURCE_IN_COLLECTION = 1 << 3 }; struct _EBookShellSidebar { diff --git a/modules/addressbook/e-book-shell-view.c b/modules/addressbook/e-book-shell-view.c index 53136c2e02..c8ef07441d 100644 --- a/modules/addressbook/e-book-shell-view.c +++ b/modules/addressbook/e-book-shell-view.c @@ -201,8 +201,9 @@ book_shell_view_update_actions (EShellView *shell_view) gboolean any_contacts_selected; gboolean has_primary_source; gboolean multiple_contacts_selected; - gboolean primary_source_is_removable; gboolean primary_source_is_writable; + gboolean primary_source_is_removable; + gboolean primary_source_in_collection; gboolean single_contact_selected; gboolean selection_is_contact_list; gboolean selection_has_email; @@ -235,10 +236,12 @@ book_shell_view_update_actions (EShellView *shell_view) has_primary_source = (state & E_BOOK_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE); - primary_source_is_removable = - (state & E_BOOK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_REMOVABLE); primary_source_is_writable = (state & E_BOOK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_WRITABLE); + primary_source_is_removable = + (state & E_BOOK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_REMOVABLE); + primary_source_in_collection = + (state & E_BOOK_SHELL_SIDEBAR_PRIMARY_SOURCE_IN_COLLECTION); any_contacts_selected = (single_contact_selected || multiple_contacts_selected); @@ -264,7 +267,9 @@ book_shell_view_update_actions (EShellView *shell_view) gtk_action_set_sensitive (action, sensitive); action = ACTION (ADDRESS_BOOK_RENAME); - sensitive = primary_source_is_writable; + sensitive = + primary_source_is_writable && + !primary_source_in_collection; gtk_action_set_sensitive (action, sensitive); action = ACTION (ADDRESS_BOOK_STOP); diff --git a/modules/calendar/e-cal-shell-sidebar.c b/modules/calendar/e-cal-shell-sidebar.c index 63d14658d5..fa58514806 100644 --- a/modules/calendar/e-cal-shell-sidebar.c +++ b/modules/calendar/e-cal-shell-sidebar.c @@ -749,9 +749,11 @@ cal_shell_sidebar_check_state (EShellSidebar *shell_sidebar) { ECalShellSidebar *cal_shell_sidebar; ESourceSelector *selector; + ESourceRegistry *registry; ESource *source; - gboolean removable = FALSE; - gboolean writable = FALSE; + gboolean is_writable = FALSE; + gboolean is_removable = FALSE; + gboolean in_collection = FALSE; gboolean refresh_supported = FALSE; gboolean has_primary_source = FALSE; guint32 state = 0; @@ -759,17 +761,25 @@ cal_shell_sidebar_check_state (EShellSidebar *shell_sidebar) cal_shell_sidebar = E_CAL_SHELL_SIDEBAR (shell_sidebar); selector = e_cal_shell_sidebar_get_selector (cal_shell_sidebar); source = e_source_selector_ref_primary_selection (selector); + registry = e_source_selector_get_registry (selector); if (source != NULL) { EClient *client; + ESource *collection; const gchar *uid; has_primary_source = TRUE; + is_writable = e_source_get_writable (source); + is_removable = e_source_get_removable (source); - uid = e_source_get_uid (source); - removable = e_source_get_removable (source); - writable = e_source_get_writable (source); + collection = e_source_registry_find_extension ( + registry, source, E_SOURCE_EXTENSION_COLLECTION); + if (collection != NULL) { + in_collection = TRUE; + g_object_unref (collection); + } + uid = e_source_get_uid (source); client = g_hash_table_lookup ( cal_shell_sidebar->priv->client_table, uid); refresh_supported = @@ -781,10 +791,12 @@ cal_shell_sidebar_check_state (EShellSidebar *shell_sidebar) if (has_primary_source) state |= E_CAL_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE; - if (removable) - state |= E_CAL_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_REMOVABLE; - if (writable) + if (is_writable) state |= E_CAL_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_WRITABLE; + if (is_removable) + state |= E_CAL_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_REMOVABLE; + if (in_collection) + state |= E_CAL_SHELL_SIDEBAR_PRIMARY_SOURCE_IN_COLLECTION; if (refresh_supported) state |= E_CAL_SHELL_SIDEBAR_SOURCE_SUPPORTS_REFRESH; diff --git a/modules/calendar/e-cal-shell-sidebar.h b/modules/calendar/e-cal-shell-sidebar.h index 2ddfff0a20..06eece93d3 100644 --- a/modules/calendar/e-cal-shell-sidebar.h +++ b/modules/calendar/e-cal-shell-sidebar.h @@ -56,9 +56,10 @@ typedef struct _ECalShellSidebarPrivate ECalShellSidebarPrivate; enum { E_CAL_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE = 1 << 0, - E_CAL_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_REMOVABLE = 1 << 1, - E_CAL_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_WRITABLE = 1 << 2, - E_CAL_SHELL_SIDEBAR_SOURCE_SUPPORTS_REFRESH = 1 << 3 + E_CAL_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_WRITABLE = 1 << 1, + E_CAL_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_REMOVABLE = 1 << 2, + E_CAL_SHELL_SIDEBAR_PRIMARY_SOURCE_IN_COLLECTION = 1 << 3, + E_CAL_SHELL_SIDEBAR_SOURCE_SUPPORTS_REFRESH = 1 << 4 }; struct _ECalShellSidebar { diff --git a/modules/calendar/e-cal-shell-view.c b/modules/calendar/e-cal-shell-view.c index d349882a82..39386bd036 100644 --- a/modules/calendar/e-cal-shell-view.c +++ b/modules/calendar/e-cal-shell-view.c @@ -395,8 +395,9 @@ cal_shell_view_update_actions (EShellView *shell_view) gboolean editable = TRUE; gboolean has_mail_identity; gboolean has_primary_source; - gboolean primary_source_is_removable; gboolean primary_source_is_writable; + gboolean primary_source_is_removable; + gboolean primary_source_in_collection; gboolean recurring = FALSE; gboolean is_instance = FALSE; gboolean is_meeting = FALSE; @@ -509,10 +510,12 @@ cal_shell_view_update_actions (EShellView *shell_view) has_primary_source = (state & E_CAL_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE); - primary_source_is_removable = - (state & E_CAL_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_REMOVABLE); primary_source_is_writable = (state & E_CAL_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_WRITABLE); + primary_source_is_removable = + (state & E_CAL_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_REMOVABLE); + primary_source_in_collection = + (state & E_CAL_SHELL_SIDEBAR_PRIMARY_SOURCE_IN_COLLECTION); refresh_supported = (state & E_CAL_SHELL_SIDEBAR_SOURCE_SUPPORTS_REFRESH); @@ -533,7 +536,9 @@ cal_shell_view_update_actions (EShellView *shell_view) gtk_action_set_sensitive (action, sensitive); action = ACTION (CALENDAR_RENAME); - sensitive = primary_source_is_writable; + sensitive = + primary_source_is_writable && + !primary_source_in_collection; gtk_action_set_sensitive (action, sensitive); action = ACTION (CALENDAR_SEARCH_PREV); diff --git a/modules/calendar/e-memo-shell-sidebar.c b/modules/calendar/e-memo-shell-sidebar.c index bc342830b2..d2cf143897 100644 --- a/modules/calendar/e-memo-shell-sidebar.c +++ b/modules/calendar/e-memo-shell-sidebar.c @@ -661,9 +661,11 @@ memo_shell_sidebar_check_state (EShellSidebar *shell_sidebar) { EMemoShellSidebar *memo_shell_sidebar; ESourceSelector *selector; + ESourceRegistry *registry; ESource *source; - gboolean removable = FALSE; - gboolean writable = FALSE; + gboolean is_writable = FALSE; + gboolean is_removable = FALSE; + gboolean in_collection = FALSE; gboolean refresh_supported = FALSE; gboolean has_primary_source = FALSE; guint32 state = 0; @@ -671,17 +673,25 @@ memo_shell_sidebar_check_state (EShellSidebar *shell_sidebar) memo_shell_sidebar = E_MEMO_SHELL_SIDEBAR (shell_sidebar); selector = e_memo_shell_sidebar_get_selector (memo_shell_sidebar); source = e_source_selector_ref_primary_selection (selector); + registry = e_source_selector_get_registry (selector); if (source != NULL) { EClient *client; + ESource *collection; const gchar *uid; has_primary_source = TRUE; + is_writable = e_source_get_writable (source); + is_removable = e_source_get_removable (source); - uid = e_source_get_uid (source); - removable = e_source_get_removable (source); - writable = e_source_get_writable (source); + collection = e_source_registry_find_extension ( + registry, source, E_SOURCE_EXTENSION_COLLECTION); + if (collection != NULL) { + in_collection = TRUE; + g_object_unref (collection); + } + uid = e_source_get_uid (source); client = g_hash_table_lookup ( memo_shell_sidebar->priv->client_table, uid); refresh_supported = @@ -693,10 +703,12 @@ memo_shell_sidebar_check_state (EShellSidebar *shell_sidebar) if (has_primary_source) state |= E_MEMO_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE; - if (removable) - state |= E_MEMO_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_REMOVABLE; - if (writable) + if (is_writable) state |= E_MEMO_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_WRITABLE; + if (is_removable) + state |= E_MEMO_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_REMOVABLE; + if (in_collection) + state |= E_MEMO_SHELL_SIDEBAR_PRIMARY_SOURCE_IN_COLLECTION; if (refresh_supported) state |= E_MEMO_SHELL_SIDEBAR_SOURCE_SUPPORTS_REFRESH; diff --git a/modules/calendar/e-memo-shell-sidebar.h b/modules/calendar/e-memo-shell-sidebar.h index b0de9f5fe4..c30073e0be 100644 --- a/modules/calendar/e-memo-shell-sidebar.h +++ b/modules/calendar/e-memo-shell-sidebar.h @@ -55,9 +55,10 @@ typedef struct _EMemoShellSidebarPrivate EMemoShellSidebarPrivate; enum { E_MEMO_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE = 1 << 0, - E_MEMO_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_REMOVABLE = 1 << 1, - E_MEMO_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_WRITABLE = 1 << 2, - E_MEMO_SHELL_SIDEBAR_SOURCE_SUPPORTS_REFRESH = 1 << 3 + E_MEMO_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_WRITABLE = 1 << 1, + E_MEMO_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_REMOVABLE = 1 << 2, + E_MEMO_SHELL_SIDEBAR_PRIMARY_SOURCE_IN_COLLECTION = 1 << 3, + E_MEMO_SHELL_SIDEBAR_SOURCE_SUPPORTS_REFRESH = 1 << 4 }; struct _EMemoShellSidebar { diff --git a/modules/calendar/e-memo-shell-view.c b/modules/calendar/e-memo-shell-view.c index 930ac6bcb0..34c9704a0d 100644 --- a/modules/calendar/e-memo-shell-view.c +++ b/modules/calendar/e-memo-shell-view.c @@ -184,8 +184,9 @@ memo_shell_view_update_actions (EShellView *shell_view) gboolean any_memos_selected; gboolean has_primary_source; gboolean multiple_memos_selected; - gboolean primary_source_is_removable; gboolean primary_source_is_writable; + gboolean primary_source_is_removable; + gboolean primary_source_in_collection; gboolean selection_has_url; gboolean single_memo_selected; gboolean sources_are_editable; @@ -213,10 +214,12 @@ memo_shell_view_update_actions (EShellView *shell_view) has_primary_source = (state & E_MEMO_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE); - primary_source_is_removable = - (state & E_MEMO_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_REMOVABLE); primary_source_is_writable = (state & E_MEMO_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_WRITABLE); + primary_source_is_removable = + (state & E_MEMO_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_REMOVABLE); + primary_source_in_collection = + (state & E_MEMO_SHELL_SIDEBAR_PRIMARY_SOURCE_IN_COLLECTION); refresh_supported = (state & E_MEMO_SHELL_SIDEBAR_SOURCE_SUPPORTS_REFRESH); @@ -257,7 +260,9 @@ memo_shell_view_update_actions (EShellView *shell_view) gtk_action_set_sensitive (action, sensitive); action = ACTION (MEMO_LIST_RENAME); - sensitive = primary_source_is_writable; + sensitive = + primary_source_is_writable && + !primary_source_in_collection; gtk_action_set_sensitive (action, sensitive); action = ACTION (MEMO_OPEN); diff --git a/modules/calendar/e-task-shell-sidebar.c b/modules/calendar/e-task-shell-sidebar.c index 9e28af2411..304e537166 100644 --- a/modules/calendar/e-task-shell-sidebar.c +++ b/modules/calendar/e-task-shell-sidebar.c @@ -661,9 +661,11 @@ task_shell_sidebar_check_state (EShellSidebar *shell_sidebar) { ETaskShellSidebar *task_shell_sidebar; ESourceSelector *selector; + ESourceRegistry *registry; ESource *source; - gboolean removable = FALSE; - gboolean writable = FALSE; + gboolean is_writable = FALSE; + gboolean is_removable = FALSE; + gboolean in_collection = FALSE; gboolean refresh_supported = FALSE; gboolean has_primary_source = FALSE; guint32 state = 0; @@ -671,17 +673,25 @@ task_shell_sidebar_check_state (EShellSidebar *shell_sidebar) task_shell_sidebar = E_TASK_SHELL_SIDEBAR (shell_sidebar); selector = e_task_shell_sidebar_get_selector (task_shell_sidebar); source = e_source_selector_ref_primary_selection (selector); + registry = e_source_selector_get_registry (selector); if (source != NULL) { EClient *client; + ESource *collection; const gchar *uid; has_primary_source = TRUE; + is_writable = e_source_get_writable (source); + is_removable = e_source_get_removable (source); - uid = e_source_get_uid (source); - removable = e_source_get_removable (source); - writable = e_source_get_writable (source); + collection = e_source_registry_find_extension ( + registry, source, E_SOURCE_EXTENSION_COLLECTION); + if (collection != NULL) { + in_collection = TRUE; + g_object_unref (collection); + } + uid = e_source_get_uid (source); client = g_hash_table_lookup ( task_shell_sidebar->priv->client_table, uid); refresh_supported = @@ -693,10 +703,12 @@ task_shell_sidebar_check_state (EShellSidebar *shell_sidebar) if (has_primary_source) state |= E_TASK_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE; - if (removable) - state |= E_TASK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_REMOVABLE; - if (writable) + if (is_writable) state |= E_TASK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_WRITABLE; + if (is_removable) + state |= E_TASK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_REMOVABLE; + if (in_collection) + state |= E_TASK_SHELL_SIDEBAR_PRIMARY_SOURCE_IN_COLLECTION; if (refresh_supported) state |= E_TASK_SHELL_SIDEBAR_SOURCE_SUPPORTS_REFRESH; diff --git a/modules/calendar/e-task-shell-sidebar.h b/modules/calendar/e-task-shell-sidebar.h index 7518a4b856..e0754f454b 100644 --- a/modules/calendar/e-task-shell-sidebar.h +++ b/modules/calendar/e-task-shell-sidebar.h @@ -55,9 +55,10 @@ typedef struct _ETaskShellSidebarPrivate ETaskShellSidebarPrivate; enum { E_TASK_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE = 1 << 0, - E_TASK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_REMOVABLE = 1 << 1, - E_TASK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_WRITABLE = 1 << 2, - E_TASK_SHELL_SIDEBAR_SOURCE_SUPPORTS_REFRESH = 1 << 3 + E_TASK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_WRITABLE = 1 << 1, + E_TASK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_REMOVABLE = 1 << 2, + E_TASK_SHELL_SIDEBAR_PRIMARY_SOURCE_IN_COLLECTION = 1 << 3, + E_TASK_SHELL_SIDEBAR_SOURCE_SUPPORTS_REFRESH = 1 << 4 }; struct _ETaskShellSidebar { diff --git a/modules/calendar/e-task-shell-view.c b/modules/calendar/e-task-shell-view.c index 6186df92d5..f7028f87d3 100644 --- a/modules/calendar/e-task-shell-view.c +++ b/modules/calendar/e-task-shell-view.c @@ -304,8 +304,9 @@ task_shell_view_update_actions (EShellView *shell_view) gboolean any_tasks_selected; gboolean has_primary_source; gboolean multiple_tasks_selected; - gboolean primary_source_is_removable; gboolean primary_source_is_writable; + gboolean primary_source_is_removable; + gboolean primary_source_in_collection; gboolean selection_has_url; gboolean selection_is_assignable; gboolean single_task_selected; @@ -342,10 +343,12 @@ task_shell_view_update_actions (EShellView *shell_view) has_primary_source = (state & E_TASK_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE); - primary_source_is_removable = - (state & E_TASK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_REMOVABLE); primary_source_is_writable = (state & E_TASK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_WRITABLE); + primary_source_is_removable = + (state & E_TASK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_REMOVABLE); + primary_source_in_collection = + (state & E_TASK_SHELL_SIDEBAR_PRIMARY_SOURCE_IN_COLLECTION); refresh_supported = (state & E_TASK_SHELL_SIDEBAR_SOURCE_SUPPORTS_REFRESH); @@ -392,7 +395,9 @@ task_shell_view_update_actions (EShellView *shell_view) gtk_action_set_sensitive (action, sensitive); action = ACTION (TASK_LIST_RENAME); - sensitive = primary_source_is_writable; + sensitive = + primary_source_is_writable && + !primary_source_in_collection; gtk_action_set_sensitive (action, sensitive); action = ACTION (TASK_MARK_COMPLETE); -- cgit v1.2.3