@@ -87,11 +87,12 @@ git_remote_branch_exists() {
8787git_check_branches () {
8888 local source_branch=" $1 "
8989 local target_branch=" $2 "
90+ local default_branch=" $3 "
9091
9192 [[ -n $source_branch ]] ||
9293 exit_error " $ERR_GIT " " Not on any branch"
9394
94- [[ $source_branch != " $( git_default_branch) " ]] ||
95+ [[ $source_branch != " ${default_branch :- $ (git_default_branch)} " ]] ||
9596 exit_error " $ERR_GIT " " On default branch"
9697
9798 git_branch_exists " $source_branch " ||
@@ -106,6 +107,22 @@ git_check_branches() {
106107 return 0
107108}
108109
110+ git_autofetch () {
111+ [[ " $GIT_MR_AUTOFETCH " == " true" ]] ||
112+ return 1 # autofetch is disabled
113+
114+ local git_dir; git_dir=$( git rev-parse --git-dir)
115+
116+ [[ -f " ${git_dir} /FETCH_HEAD" &&
117+ -z " $( find " ${git_dir} /FETCH_HEAD" -mmin +" ${GIT_MR_AUTOFETCH_INTERVAL} " 2> /dev/null) " ]] &&
118+ return 1 # last fetch is recent enough
119+
120+ local remote; remote=${1:- $(gitlab_remote || git_remote)}
121+
122+ echo_debug " Fetching remote: ${remote} "
123+ git fetch --quiet " ${remote} " 2> /dev/null
124+ }
125+
109126git_commits () {
110127 local source_branch=${1:- $(git_current_branch)}
111128 local target_branch=${2:- ${GIT_MR_TARGET:- $(git_base_branch " $source_branch " )} }
@@ -1162,6 +1179,10 @@ mr_status_block() {
11621179 local mr_url=$6
11631180 local mr_title=$7
11641181
1182+ local current_target
1183+ local source_branch
1184+ local default_branch
1185+
11651186 local parse=()
11661187 [[ -z $merge_request && -z $mr_iid ]] && parse+=(' "mr_iid=" + (.iid | @sh) + ";\n" +' )
11671188 [[ -z $mr_url ]] && parse+=(' "mr_url=" + (.web_url | @sh) + ";\n" +' )
@@ -1178,12 +1199,31 @@ mr_status_block() {
11781199
11791200 mr_print_title " $mr_title " " $mr_url "
11801201
1202+ # Update remote references
1203+ local remote; remote=$( gitlab_remote || git_remote)
1204+ git_autofetch " ${remote} "
1205+
1206+ default_branch=$( git_default_branch)
1207+
11811208 # Read merge request, approvals & threads
11821209 [[ -n $merge_request ]] || gitlab_read_mr merge_request
11831210 [[ -n $mr_approvals ]] || gitlab_read_approvals mr_approvals
11841211 [[ -n $mr_threads ]] || gitlab_read_threads mr_threads
11851212
1186- mr_print_status " $merge_request " " $mr_approvals " " $mr_threads "
1213+ eval " $( echo " $merge_request " | jq -r '
1214+ "source_branch=" + (.source_branch | @sh) + ";\n" +
1215+ "current_target=" + (.target_branch | @sh) + ";\n"
1216+ ' ) "
1217+
1218+ # Check branch lag
1219+ local mr_commits_behind mr_commits_behind_main
1220+ mr_commits_behind=$( git rev-list --count " ${source_branch} ..${remote} /${current_target} " 2> /dev/null || echo " 0" )
1221+
1222+ if [[ $current_target != " $default_branch " ]]; then
1223+ mr_commits_behind_main=$( git rev-list --count " ${source_branch} ..${remote} /${default_branch} " 2> /dev/null || echo " 0" )
1224+ fi
1225+
1226+ mr_print_status " $merge_request " " $mr_approvals " " $mr_threads " " $mr_commits_behind " " $mr_commits_behind_main "
11871227}
11881228
11891229mr_print_title () {
@@ -1200,6 +1240,8 @@ mr_print_status() {
12001240 local merge_request=$1
12011241 local approvals=$2
12021242 local threads=$3
1243+ local commits_behind=$4
1244+ local commits_behind_main=$5
12031245
12041246 [[ -n $merge_request ]] || exit_error " $ERR_MR " " merge_request not provided"
12051247
@@ -1318,12 +1360,26 @@ mr_print_status() {
13181360 ci_str=" CI: $pipeline_icon "
13191361
13201362 # Merge target
1363+ local target_str_len=$(( ${# current_target} + 4 ))
13211364 local target_display
13221365 target_display=" ${target_display} $( colorize " (\U000021A3 " " gray" ) "
13231366 target_display=" ${target_display} $( colorize " $current_target " " lightpurple" ) "
1367+
1368+ if [[ $commits_behind -gt 0 || $commits_behind_main -gt 0 ]]; then
1369+ if [[ $commits_behind -gt 0 ]]
1370+ then target_display=" ${target_display} $( colorize " ↓$commits_behind " " red" " bold" ) "
1371+ else target_display=" ${target_display} $( colorize " ↓0" " green" ) "
1372+ fi
1373+ (( target_str_len += 4 )) # space, arrow, 2 digits
1374+ fi
1375+
1376+ if [[ $commits_behind_main -gt 0 ]]; then
1377+ target_display=" ${target_display} $( colorize " ⇣$commits_behind_main " " red" ) "
1378+ (( target_str_len += 4 )) # space, arrow, 2 digits
1379+ fi
1380+
13241381 target_display=" ${target_display} $( colorize " )" " gray" ) "
13251382
1326- local target_str_len=$(( ${# current_target} + 4 ))
13271383
13281384 # Draft status
13291385 local draft_str=
@@ -1337,15 +1393,18 @@ mr_print_status() {
13371393 # Spacers for draft & target branch indicators
13381394 local display_width=76 # not counting 3 leading spaces
13391395 local spacer_chars=$(( display_width - labels_str_len - target_str_len - draft_str_len))
1340- local spacer_chars_l =0
1341- local spacer_chars_r =0
1396+ local draft_spacer_l =0
1397+ local draft_spacer_r =0
13421398
13431399 if [[ $spacer_chars -gt 0 ]]; then
1344- spacer_chars_l=$(( 43 - labels_str_len)) # 42: roughly at the same level as CI indicator
1345- spacer_chars_r=$(( spacer_chars - spacer_chars_l))
1346- if [[ $spacer_chars_r -lt 0 ]]; then
1347- spacer_chars_l=$(( spacer_chars_l + spacer_chars_r))
1348- spacer_chars_r=0
1400+ draft_spacer_l=$(( 43 - labels_str_len)) # 43: roughly at the same level as CI indicator
1401+ draft_spacer_r=$(( spacer_chars - draft_spacer_l))
1402+ if [[ $draft_spacer_r -lt 0 ]]; then
1403+ draft_spacer_l=$(( draft_spacer_l + draft_spacer_r))
1404+ draft_spacer_r=0
1405+ elif [[ $draft_spacer_l -lt 0 ]]; then
1406+ draft_spacer_r=$(( draft_spacer_l + draft_spacer_r))
1407+ draft_spacer_l=0
13491408 fi
13501409 fi
13511410
@@ -1355,14 +1414,14 @@ mr_print_status() {
13551414 # 1st row ------------------------------------------------------------------
13561415 # Labels
13571416 echo -en " \U0001F3F7 ${labels_display} "
1358- echo_spacer " $spacer_chars_l "
1417+ echo_spacer " $draft_spacer_l "
13591418 # Draft status
13601419 if [[ -n $draft_str ]]; then
13611420 echo -en " $( colorize " $draft_str " " orange" ) "
13621421 else
1363- echo_spacer $(( 2 - spacer_chars_l - spacer_chars_r ))
1422+ echo_spacer $(( 2 - draft_spacer_l - draft_spacer_r ))
13641423 fi
1365- echo_spacer " $spacer_chars_r "
1424+ echo_spacer " $draft_spacer_r "
13661425 # Target
13671426 echo " $target_display "
13681427
@@ -2321,7 +2380,9 @@ mr_update() {
23212380
23222381 local source_branch=${1:- $(git_current_branch)}
23232382 local target_branch=${GIT_MR_TARGET:- $(git_base_branch " $source_branch " )}
2324- git_check_branches " $source_branch " " $target_branch "
2383+ local default_branch; default_branch=$( git_default_branch)
2384+
2385+ git_check_branches " $source_branch " " $target_branch " " $default_branch "
23252386
23262387 # Search existing merge request
23272388 local mr_summary; mr_summary=$( gitlab_merge_request_summary " $source_branch " )
@@ -2615,9 +2676,22 @@ mr_update() {
26152676 gitlab_read_approvals mr_approvals
26162677 gitlab_read_threads mr_threads
26172678
2679+ # Re-read current_target from MR (might have changed)
2680+ eval " $( echo " $merge_request " | jq -r '
2681+ "current_target=" + (.target_branch | @sh) + ";\n"
2682+ ' ) "
2683+
2684+ # Check branch lag
2685+ local mr_commits_behind mr_commits_behind_main
2686+ mr_commits_behind=$( git rev-list --count " ${source_branch} ..${remote} /${current_target} " 2> /dev/null || echo " 0" )
2687+
2688+ if [[ $current_target != " $default_branch " ]]; then
2689+ mr_commits_behind_main=$( git rev-list --count " ${source_branch} ..${remote} /${default_branch} " 2> /dev/null || echo " 0" )
2690+ fi
2691+
26182692 # --------------------------------------------------------------------------------
26192693 mr_print_title " $mr_title " " $mr_url "
2620- mr_print_status " $merge_request " " $mr_approvals " " $mr_threads "
2694+ mr_print_status " $merge_request " " $mr_approvals " " $mr_threads " " $mr_commits_behind " " $mr_commits_behind_main "
26212695}
26222696
26232697mr_merge () {
@@ -3013,6 +3087,9 @@ EOF
30133087 | mr.git-mr-required-upvotes | GIT_MR_REQUIRED_UPVOTES |
30143088 | | |
30153089 | mr.git-mr-timeout | GIT_MR_TIMEOUT |
3090+ | | |
3091+ | mr.git-mr-autofetch | GIT_MR_AUTOFETCH |
3092+ | mr.git-mr-autofetch-interval | GIT_MR_AUTOFETCH_INTERVAL |
30163093 +---------------------------------------------+---------------------------------------+
30173094
30183095 To create a Jira API Token, go to: https://id.atlassian.com/manage-profile/security/api-tokens
@@ -3109,12 +3186,16 @@ GIT_MR_EXTENDED=${GIT_MR_EXTENDED-$(git config --get mr.git-mr-extended || true)
31093186GIT_MR_REQUIRED_UPVOTES=${GIT_MR_REQUIRED_UPVOTES:- $(git config --get mr.git-mr-required-upvotes || true)}
31103187GITLAB_REMOVE_SOURCE_BRANCH_ON_MERGE=${GITLAB_REMOVE_SOURCE_BRANCH_ON_MERGE:- $(git config --get mr.gitlab-remove-source-branch-on-merge || true)}
31113188GIT_MR_TIMEOUT=${GIT_MR_TIMEOUT:- $(git config --get mr.git-mr-timeout || true)}
3189+ GIT_MR_AUTOFETCH=${GIT_MR_AUTOFETCH:- $(git config --get mr.git-mr-autofetch || true)}
3190+ GIT_MR_AUTOFETCH_INTERVAL=${GIT_MR_AUTOFETCH_INTERVAL:- $(git config --get mr.git-mr-autofetch-interval || true)}
31123191
31133192# Defaults
31143193GITLAB_PROJECTS_LIMIT_MEMBER=${GITLAB_PROJECTS_LIMIT_MEMBER:- 1}
31153194GIT_MR_REQUIRED_UPVOTES=${GIT_MR_REQUIRED_UPVOTES:- 2}
31163195GITLAB_REMOVE_SOURCE_BRANCH_ON_MERGE=${GITLAB_REMOVE_SOURCE_BRANCH_ON_MERGE:- 1}
31173196GIT_MR_TIMEOUT=${GIT_MR_TIMEOUT:- 10}
3197+ GIT_MR_AUTOFETCH=${GIT_MR_AUTOFETCH:- false}
3198+ GIT_MR_AUTOFETCH_INTERVAL=${GIT_MR_AUTOFETCH_INTERVAL:- 5}
31183199
31193200GIT_MR_MENU_STATUS_SHOW=both
31203201# GIT_MR_MENU_STATUS_SHOW=title
0 commit comments