How do I add a co-author to latest pushed git commit?

11k views Asked by At

I need to add a co-author to my last commit and I tried using git commit --amend --author="name <[email protected]>" but change --author to --co-authored-by. I thought this would be an easily google-able fix but everything is only for authors and not co-authors.

5

There are 5 answers

0
1615903 On BEST ANSWER

"Co-author" is not a git concept. It is a convention in commit messages used by some services, including GitHub. So, the solution is to edit the actual commit message with git commit --amend and add a line to the end:

Co-Authored-By: Name <[email protected]>
0
Priya On

For commandline commit, I have created a prepare-commit-msg hook which needs to be placed inside .git/hooks/ and should be given executable permission. You can use up/down to navigate the list and space to select one or more author.

Usage: git commit -m "Message"
Note: Modify as you like as per your convenience

Ref: https://gist.github.com/smartameer/6c529bae770adbdd39bf895153564a34

#!/bin/bash

function prompt_for_multiselect {

    # little helpers for terminal print control and key input
    GREEN='\033[00;32m'
    YELLOW='\033[00;33m'
    RESTORE='\033[0m'
    ESC=$( printf "\033")
    cursor_blink_on()   { printf "$ESC[?25h"; }
    cursor_blink_off()  { printf "$ESC[?25l"; }
    cursor_to()         { printf "$ESC[$1;${2:-1}H"; }
    print_inactive()    { printf "$2   $1 $RESTORE"; }
    print_active()      { printf "$YELLOW$2  $ESC[7m $1 $RESTORE$ESC[27m"; }
    get_cursor_row()    { IFS=';' read -sdR -p $'\E[6n' ROW COL; echo ${ROW#*[}; }
    key_input()         {
        local key
        IFS= read -rsn1 key 2>/dev/null >&2
        if [[ $key = ""      ]]; then echo enter; fi;
            if [[ $key = $'\x20' ]]; then echo space; fi;
                if [[ $key = $'\x1b' ]]; then
                    read -rsn2 key
                    if [[ $key = [A ]]; then echo up;    fi;
                        if [[ $key = [B ]]; then echo down;  fi;
                fi
            }
        toggle_option()    {
            local arr_name=$1
            eval "local arr=(\"\${${arr_name}[@]}\")"
            local option=$2
            if [[ ${arr[option]} == true ]]; then
                arr[option]=
            else
                arr[option]=true
            fi
            eval $arr_name='("${arr[@]}")'
        }

    local retval=$1
    local options
    local defaults

    IFS=';' read -r -a options <<< "$2"
    if [[ -z $3 ]]; then
        defaults=()
    else
        IFS=';' read -r -a defaults <<< "$3"
    fi
    local selected=()

    for ((i=0; i<${#options[@]}; i++)); do
        selected+=("${defaults[i]:-false}")
        printf "\n"
    done

    # determine current screen position for overwriting the options
    local lastrow=`get_cursor_row`
    local startrow=$(($lastrow - ${#options[@]}))

    # ensure cursor and input echoing back on upon a ctrl+c during read -s
    trap "cursor_blink_on; stty echo; printf '\n'; exit" 2
    cursor_blink_off

    local active=0
    while true; do
        # print options by overwriting the last lines
        local idx=0
        for option in "${options[@]}"; do
            local prefix="$RESET ◻︎"
            if [[ ${selected[idx]} == true ]]; then
                prefix="$GREEN ◼︎"
            fi

            cursor_to $(($startrow + $idx))
            if [ $idx -eq $active ]; then
                print_active "$option" "$prefix"
            else
                print_inactive "$option" "$prefix"
            fi
            ((idx++))
        done

        # user key control
        case `key_input` in
            space)  toggle_option selected $active;;
            enter)  break;;
            up)     ((active--));
                if [ $active -lt 0 ]; then active=$((${#options[@]} - 1)); fi;;
            down)   ((active++));
                if [ $active -ge ${#options[@]} ]; then active=0; fi;;
        esac
    done

    # cursor position back to normal
    cursor_to $lastrow
    printf "\n"
    cursor_blink_on

    eval $retval='("${selected[@]}")'
}

exec < /dev/tty

echo 'Please select from the authors list:'
AUTHORS=$(git shortlog -sce | cut -c8-)
AUTHORS_LIST=()

while read -r line; do
    if ! [[ "$line" =~ ^.*\|.*$ ]]; then
        AUTHORS_LIST+=("${line}")
        OPTIONS_STRING+="${line};"
    fi
done <<< "$AUTHORS"

prompt_for_multiselect SELECTED "$OPTIONS_STRING"
MESSAGE="\n\n"

for i in "${!SELECTED[@]}"; do
    if [ "${SELECTED[$i]}" == "true" ]; then
        MESSAGE="${MESSAGE}Co-authored-by: ${AUTHORS_LIST[$i]}\n"
    fi
done

exec <&-

sed -i.bak -e "1s/$/$MESSAGE/" $1

Commit

0
Guildenstern On

Stealing/appropriating an answer from another question:

git commit --amend -m"$(git log --format=%B -n1)" -m"Co-authored-by: Anon"

Tested with Bash.

Alternative using git-interpret-trailers

git commit --amend -m"$(git log --format=%B -n1 | git interpret-trailers --trailer 'Co-authored-by: Anon')"
0
l0b0 On

You can use this Git alias to add yourself as co-author of the most recent commit in a single command:

co-author = !git commit --amend --message=\"$(git show --format=%B --no-patch HEAD)\" --message=\"$(printf 'Co-Authored-By: %s <%s>' \"$(git config --get user.name)\" \"$(git config --get user.email)\")\"

Just run git co-author, and the last commit should be updated.

0
Devon McGrath On

Its possible to do this, but I would be careful where and when you do it. Essentially, don't do this in your main branch, or any shared branch. It will break pending PR's and force anyone else to reset the remote.

If you're in a feature branch that hasn't been merged to a shared branch yet, then the following will work:


In your local repo, make sure its up to date:

git fetch --all
git pull 

Then start an interactive rebase, and specify how far back the commit you want to edit is with HEAD~N, in your case target the most recent with HEAD~1:

git rebase -i HEAD~1

then change the message to what you want via:

git commit --amend -m

In your case, to add Co-Author add some space between the title and followed by



Co-authored By: Name <[email protected]>

You should be able to see the changes with git log. If you're happy you can push the changes:

git push --force-with-lease {remote} {branch}

--force-with-lease is required as the commit history has changed. Otherwise your push will fail.