• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/bin/bash
2# Copyright 2021 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5#
6# Script to create a commit to merge cros/main into cros/chromeos with a useful
7# commit message.
8#
9# Basic usage to upload a merge to gerrit:
10#
11#   $ repo start uprev .
12#   $ ./tools/chromeos/create_merge
13#   $ git push cros HEAD:refs/for/chromeos
14#
15# To merge with a specific commit, use: ./tools/chromeos/create_merge $SHA
16
17set -e
18
19if [ "$1" == "--dry-run-only" ]; then
20    DRY_RUN_ONLY=true
21    shift
22fi
23
24LOCAL_BRANCH=$(git branch --show-current)
25REMOTE_NAME=$(git config "branch.${LOCAL_BRANCH}.remote")
26URL=$(git remote get-url "${REMOTE_NAME}")
27
28DEFAULT_TARGET="${REMOTE_NAME}/main"
29MERGE_TARGET="${1:-${DEFAULT_TARGET}}"
30
31commit_list() {
32    git log --oneline --decorate=no --no-color "HEAD..${MERGE_TARGET}"
33}
34
35prerequisites() {
36    if [[ -e "${LOCAL_BRANCH}" ]] ||
37        [[ -e "${REMOTE_NAME}" ]] ||
38        [[ -e "${URL}" ]]; then
39        echo "This script requires the local repository to be on" \
40            "a tracking branch."
41        exit 1
42    fi
43
44    if [[ -n $(git status -s) ]]; then
45        echo "Working directory is not clean:"
46        git status -s
47        exit 1
48    fi
49
50    if [[ -z "$(commit_list)" ]]; then
51        echo "Nothing to merge."
52        exit 0
53    fi
54}
55
56cq_depends() {
57    git log --no-color "HEAD..${MERGE_TARGET}" --pretty=email |
58        grep ^Cq-Depend: |
59        sort -u
60}
61
62bug_references() {
63    git log --no-color "HEAD..${MERGE_TARGET}" --pretty=email |
64        grep ^BUG= |
65        grep -vi ^BUG=none |
66        sort -u
67}
68
69merge_message() {
70    local old=$(git rev-parse HEAD)
71    local new=$(git rev-parse "${MERGE_TARGET}")
72    local count=$(commit_list | wc -l)
73
74    local notes="$(date +%F)"
75    if [[ -n "$(cq_depends)" ]]; then
76        notes="${notes}, cq-depend"
77    fi
78
79    if [ "${DRY_RUN_ONLY}" = true ]; then
80        echo "Merge dry run (${notes})"
81    else
82        echo "Merge ${count} commits from ${MERGE_TARGET} (${notes})"
83    fi
84    echo ""
85    commit_list
86    echo ""
87    echo "${URL}/+log/${old}..${new}"
88    echo ""
89    if [ "${DRY_RUN_ONLY}" != true ]; then
90        bug_references
91    fi
92    echo "TEST=CQ"
93}
94
95merge_trailers() {
96    cq_depends
97    if [ "${DRY_RUN_ONLY}" = true ]; then
98        echo "Commit: false"
99    fi
100}
101
102main() {
103    prerequisites
104    # Note: trailers need to be added in a separate -m argument. Otherwise trailing whitespace may
105    # be trimmed which can confuse the gerrit preupload hook when it's trying to add the Commit-Id
106    # trailer.
107    git merge -X theirs --no-ff "${MERGE_TARGET}" -m "$(merge_message)" -m "$(merge_trailers)"
108
109    git --no-pager log -n 1
110}
111
112main
113