ฉันสามารถระบุผู้ใช้หลายคนด้วยตนเองใน. gitconfig ได้หรือไม่


755

ในฉัน~/.gitconfigฉันจะแสดงที่อยู่อีเมลส่วนตัวของฉันใต้[user]เพราะนั่นคือสิ่งที่ฉันต้องการใช้สำหรับ repos Github

แต่ฉันเพิ่งเริ่มใช้คอมไพล์ในการทำงานด้วยเช่นกัน repo คอมไพล์ของ บริษัท ของฉันอนุญาตให้ฉันส่งมอบ แต่เมื่อมันส่งประกาศการเปลี่ยนแปลงใหม่มันบอกว่าพวกเขามาจาก Anonymous เพราะไม่รู้จักที่อยู่อีเมลในของฉัน.gitconfig- อย่างน้อยนั่นคือทฤษฎีของฉัน

เป็นไปได้หรือไม่ที่จะระบุ[user]คำจำกัดความหลายคำ .gitconfigหรือมีวิธีอื่นที่จะแทนที่ค่าเริ่มต้น.gitconfigสำหรับไดเรกทอรีที่แน่นอนหรือไม่ ในกรณีของฉันฉันตรวจสอบรหัสการทำงานทั้งหมด~/worksrc/- มีวิธีการระบุ.gitconfigเฉพาะไดเรกทอรีนั้น (และไดเรกทอรีย่อย) หรือไม่


ดูGit-config # ไฟล์
Josh Lee

1
ฉันประหลาดใจที่เซิร์ฟเวอร์ บริษัท ของคุณจะทำเช่นนั้น - จะต้องเปลี่ยนรูปแบบการดำเนินการของคุณเพื่อให้ทำงานได้ หากคุณยืนยันการชำระเงินในท้องถิ่นคุณจะเห็นชื่อผู้ใช้อะไร
Alex Brown

1
@Alex: ลืมบิตสำคัญที่นั่น - มันอาจเป็นเพียงชื่อในการแจ้งเตือนทางอีเมลไม่ใช่การเปลี่ยนแปลงอะไรเลยในการส่ง
Cascabel

1
คุณสามารถใช้ git-hook เพื่อทำให้งานที่เกิดซ้ำนี้เป็นไปโดยอัตโนมัติ: github.com/DrVanScott/git-clone-init
Henning

1
โปรดยอมรับคำตอบนี้: stackoverflow.com/a/43654115/482899 เป็นทางออกที่ดีที่สุดตั้งแต่ git 2.13
northtree

คำตอบ:


1017

คุณสามารถกำหนดค่า repo แต่ละรายการเพื่อใช้ผู้ใช้ / ที่อยู่อีเมลที่เฉพาะเจาะจงซึ่งแทนที่การกำหนดค่าส่วนกลาง จากรากของ repo ให้เรียกใช้

git config user.name "Your Name Here"
git config user.email your@email.com

ในขณะที่ผู้ใช้ / อีเมลเริ่มต้นมีการกำหนดค่าใน ~ / .gitconfig ของคุณ

git config --global user.name "Your Name Here"
git config --global user.email your@email.com

83
คุณสามารถดูผลของการตั้งค่าเหล่านี้ได้ใน.git/configไฟล์
Abizern

21
คุณสามารถแก้ไขไฟล์ config ของผู้ที่มีและgit config --edit git config --global --editและในกรณีที่คุณพลาด Abizern ของความคิดเห็น , ไฟล์ config <repo-root>/.git/configที่เก็บของที่
Rory O'Kane

13
คุณควรยกเลิกการตั้งค่าGIT_AUTHOR_EMAILและGIT_COMMITTER_EMAIL (และ * _NAME) เนื่องจากจะแทนที่การตั้งค่าท้องถิ่น
ACyclic

6
มีวิธีทำเช่นนี้สำหรับ repos ทั้งหมดในโฟลเดอร์ที่กำหนดแทนที่จะเป็น repos แต่ละรายการหรือไม่? ดูคำถามของฉันที่นี่: stackoverflow.com/questions/21307793/…
scubbo

6
ดูคำตอบด้านล่างนี้เพื่อดูวิธีแก้ปัญหาล่าสุดที่Git 2.13เผยแพร่ในวันนี้
tejasbubane

491

ตั้งแต่ Git 2.13ก็เป็นไปได้ที่จะแก้ปัญหานี้โดยใช้ที่เพิ่งแนะนำเงื่อนไขรวมถึง

ตัวอย่าง:

โกลบอล config ~ / .gitconfig

[user]
    name = John Doe
    email = john@doe.tld

[includeIf "gitdir:~/work/"]
    path = ~/work/.gitconfig

ทำงาน config ที่เฉพาะเจาะจง~ / work / .gitconfig

[user]
    email = john.doe@company.tld

48
นี่เป็นคำตอบที่ดีที่สุดในขณะนี้ที่ git 2.13 เปิดตัวแล้ว
tejasbubane

1
โซลูชันนี้จะทำงานกับไดเรกทอรีย่อยทั้งหมดภายในไดเรกทอรีที่ระบุไว้ในคำสั่ง include หรือไม่หากไม่มีไฟล์. gitconfig ของตนเอง ฉันคิดอย่างนั้น แต่การทดสอบที่ผ่านมาก็ยังไม่ได้รับผลกระทบนี้
Gary

2
@ แกรี่ใช่ตามประสบการณ์ของฉันและเอกสาร: "หากรูปแบบลงท้ายด้วย /, ** จะถูกเพิ่มโดยอัตโนมัติ ตัวอย่างเช่นรูปแบบ foo / กลายเป็น foo / ** กล่าวอีกนัยหนึ่งมันตรงกับ "foo" และทุกสิ่งที่อยู่ภายในเรียกซ้ำ ","; รวมสำหรับที่เก็บทั้งหมดใน $ HOME / to / group [includeIf "gitdir: ~ / to / group /"]”
TomášJanoušek

6
gitdirควรจะรวมถึงล่าสุด '/'
Chris Yim

5
คุณสามารถตรวจสอบว่ามันทำงานซ้ำโดยการเรียกใช้git config --listในไดเรกทอรีที่แตกต่างกัน ในไดเร็กทอรีย่อย~/work/ที่มีที่เก็บ git includeIfจะมีผล โปรดทราบว่าในไดเรกทอรีย่อย~/work/ที่ไม่มีที่เก็บ git includeIfจะไม่ถูกเรียกใช้งาน
NZD

105

หรือคุณสามารถเพิ่มข้อมูลต่อไปนี้ใน.git/configไฟล์ในเครื่องของคุณ

[user]  
    name = Your Name
    email = your.email@gmail.com

27
... ซึ่งเป็นวิธีการด้วยตนเองในการทำสิ่งที่คำสั่งที่ @discomurray แนะนำให้คุณ
user456584

1
เป็นไปได้หรือไม่ที่จะเพิ่มหลายบรรทัดของสิ่งนี้ต่อรีโมต
Abel Callejo

55

หนึ่งคำสั่งบัญชี GitHub สลับ

วิธีนี้ใช้รูปแบบของนามแฝง git เดียว เมื่อดำเนินการแล้วผู้ใช้โครงการปัจจุบันจะถูกแนบไปกับบัญชีอื่น

สร้างคีย์ ssh

ssh-keygen -t rsa -C "rinquin.arnaud@gmail.com" -f '/Users/arnaudrinquin/.ssh/id_rsa'

[...]

ssh-keygen -t rsa -C "arnaud.rinquin@wopata.com" -f '/Users/arnaudrinquin/.ssh/id_rsa_pro'

เชื่อมโยงไปยังบัญชี GitHub / Bitbucket ของคุณ

  1. คัดลอกกุญแจสาธารณะเริ่มต้น pbcopy < ~/.ssh/id_rsa.pub
  2. ลงชื่อเข้าใช้บัญชี GitHub ของคุณ
  3. วางกุญแจในadd SSH keyหน้า GitHub
  4. คัดลอกกุญแจสาธารณะอื่น ๆ pbcopy < ~/.ssh/id_rsa_pro.pub
  5. ทำซ้ำและปรับขั้นตอนที่ 2 ถึง 4 สำหรับบัญชีอื่น ๆ

ขั้นตอนที่ 1 การสลับคีย์อัตโนมัติ

เราสามารถกำหนดค่าการส่งใช้คีย์การเข้ารหัสที่เฉพาะเจาะจงขึ้นอยู่กับที่ssh สิ่งที่ดีคือการที่คุณสามารถมีนามแฝงหลายเดียวกันhosthostname

ดู~/.ssh/configไฟล์ตัวอย่างนี้:

# Default GitHub
Host github.com
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_rsa

# Professional github alias
Host github_pro
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_rsa_pro

git การกำหนดค่าระยะไกล

ตอนนี้คุณสามารถใช้ชื่อแทนเหล่านี้ในรีโมทคอมไพล์โดยการเปลี่ยนจากgit@github.comgit@github_pro

คุณสามารถเปลี่ยนโครงการที่มีอยู่ของคุณรีโมท (ใช้สิ่งที่ต้องการgit remote set-url origin git@github_pro:foo/bar.git) หรือปรับใช้โดยตรงเมื่อทำการโคลน

git clone git@github.com:ArnaudRinquin/atom-zentabs.git

ใช้นามแฝงมันกลายเป็น:

git clone git@github_pro:ArnaudRinquin/atom-zentabs.git

ขั้นตอนที่ 2 เปลี่ยน git user.email

การตั้งค่า Git สามารถเป็นแบบโกลบอลหรือต่อโปรเจ็กต์ ในกรณีของเราเราต้องการการตั้งค่าต่อโครงการ มันง่ายมากที่จะเปลี่ยน:

git config user.email 'arnaud.rinquin@wopata.com'

ในขณะนี้เป็นเรื่องง่าย แต่จะใช้เวลานานสำหรับนักพัฒนาที่เราเป็น เราสามารถเขียนนามแฝงคอมไพล์ที่ง่ายมากสำหรับสิ่งนั้น

เรากำลังจะเพิ่มลงใน~/.gitconfigไฟล์

[user]
    name = Arnaud Rinquin
    email = rinquin.arnaud@gmail.com

...

[alias]
    setpromail = "config user.email 'arnaud.rinquin@wopata.com'"

จากนั้นสิ่งที่เราต้องทำคือgit setpromailเปลี่ยนอีเมลของเราสำหรับโครงการนี้เท่านั้น

ขั้นตอนที่ 3. สวิตช์คำสั่งเดียวโปรด!

มันจะดีหรือไม่ที่จะเปลี่ยนจากบัญชีเริ่มต้นเป็นบัญชีที่ระบุด้วยคำสั่งแบบไม่มีพารามิเตอร์เดียว? เป็นไปได้อย่างแน่นอน คำสั่งนี้จะมีสองขั้นตอน:

  • เปลี่ยนรีโมทโครงการปัจจุบันเป็นนามแฝงที่เลือก
  • เปลี่ยนการกำหนดค่าผู้ใช้โครงการปัจจุบันอีเมล

เรามีโซลูชันคำสั่งเดียวสำหรับขั้นตอนที่สองแล้ว แต่โซลูชันแรกนั้นยากกว่ากัน เปลี่ยนโฮสต์รีโมตคำสั่งเดียว

ต่อไปนี้เป็นวิธีแก้ปัญหาในรูปแบบของคำสั่ง git alias อื่นเพื่อเพิ่มใน~/.gitconfig:

[alias]
  changeremotehost = !sh -c \"git remote -v | grep '$1.*fetch' | sed s/..fetch.// | sed s/$1/$2/ | xargs git remote set-url\"

สิ่งนี้อนุญาตให้เปลี่ยนรีโมตทั้งหมดจากโฮสต์หนึ่งเป็นโฮสต์อื่น (นามแฝง) ดูตัวอย่าง:

$ > git remote -v
origin  git@github.com:ArnaudRinquin/arnaudrinquin.github.io.git (fetch)
origin  git@github.com:ArnaudRinquin/arnaudrinquin.github.io.git (push)

$ > git changeremotehost github.com github_pro

$ > git remote -v
origin  git@github_pro:ArnaudRinquin/arnaudrinquin.github.io.git (fetch)
origin  git@github_pro:ArnaudRinquin/arnaudrinquin.github.io.git (push)

รวมพวกเขาทั้งหมด

ตอนนี้เราต้องรวมคำสั่งทั้งสองเป็นหนึ่งเดียวมันค่อนข้างง่าย มาดูกันว่าฉันยังผสานรวมการสลับโฮสต์บิตบิตด้วยวิธีใด

[alias]
  changeremotehost = !sh -c \"git remote -v | grep '$1.*fetch' | sed s/..fetch.// | sed s/$1/$2/ | xargs git remote set-url\"
  setpromail = "config user.email 'arnaud.rinquin@wopata.com'"
  gopro = !sh -c \"git changeremotehost github.com github_pro && git changeremotehost bitbucket.com bitbucket_pro && git setpromail\"

ลิงค์แหล่งที่มา -Tutorial


มันยอดเยี่ยมมากขอบคุณ ฉันทำงานกับ repos จำนวนมากต่ออีเมลดังนั้นsetpromailชื่อแทนของฉันจึงใช้config --globalแทน (และฉันมีชื่อแทนชุดอื่นสำหรับตั้งค่าที่อยู่อีเมลอื่น) มันได้ผล!
เชล - slm

1
สำหรับทั้งสองบัญชีต่างกันฉันจะลงชื่อด้วยคีย์ gpg ที่แตกต่างกันได้อย่างไร ฉันมีปุ่ม 2x gpg สำหรับบัญชี 2x github และต้องการลงชื่อต่างกัน "git config --global user.signingkey xxxx"
hakkican

คำตอบนี้ยอดเยี่ยม ฉันเกือบจะไม่ได้อ่านมันเพราะฉันคิดว่าฉันเจออะไรจากคำตอบอื่น สมควรได้รับการโหวตมากขึ้นแน่นอน PS มันจะดียิ่งขึ้นเมื่อรวมกับuseConfigOnly = trueจากคำตอบอื่น ๆ
steinybot

ไม่ได้ระบุ IdentifyFile มันเป็น IdenfityFile
คริสเตียน

40

หลังจากได้รับแรงบันดาลใจบางส่วนจากโพสต์บล็อกของ Orr Sellaฉันได้เขียนฮุก (ที่อยู่~/.git/templates/hooks) ซึ่งจะตั้งชื่อผู้ใช้และที่อยู่อีเมลที่เฉพาะเจาะจงตามข้อมูลที่อยู่ในตัวแทนท้องถิ่น./.git/config:

คุณต้องวางเส้นทางไปยังไดเรกทอรีแม่แบบของคุณ~/.gitconfig:

[init]
    templatedir = ~/.git/templates

จากนั้นแต่ละคนgit initหรือจะรับเบ็ดที่และจะใช้ข้อมูลของผู้ใช้ในช่วงต่อไปgit clone git commitหากคุณต้องการใช้ตะขอเพื่อ repos แล้ว exositing แล้วเพียงเรียกใช้git initrepo ภายในเพื่อเริ่มต้นใหม่

นี่คือตะขอที่ฉันคิดขึ้นมา (มันยังคงต้องการการขัดบ้าง - ยินดีให้คำแนะนำ) บันทึกทั้งเป็น

~/.git/templates/hooks/pre_commit

หรือ

~/.git/templates/hooks/post-checkout

และตรวจสอบให้แน่ใจว่าสามารถปฏิบัติการได้: chmod +x ./post-checkout || chmod +x ./pre_commit

#!/usr/bin/env bash

# -------- USER CONFIG
# Patterns to match a repo's "remote.origin.url" - beginning portion of the hostname
git_remotes[0]="Github"
git_remotes[1]="Gitlab"

# Adjust names and e-mail addresses
local_id_0[0]="my_name_0"
local_id_0[1]="my_email_0"

local_id_1[0]="my_name_1"
local_id_1[1]="my_email_1"

local_fallback_id[0]="${local_id_0[0]}"
local_fallback_id[1]="${local_id_0[1]}"


# -------- FUNCTIONS
setIdentity()
{
    local current_id local_id

    current_id[0]="$(git config --get --local user.name)"
    current_id[1]="$(git config --get --local user.email)"

    local_id=("$@")

    if [[ "${current_id[0]}" == "${local_id[0]}" &&
          "${current_id[1]}" == "${local_id[1]}" ]]; then
        printf " Local identity is:\n"
        printf "»  User: %s\n»  Mail: %s\n\n" "${current_id[@]}"
    else
        printf "»  User: %s\n»  Mail: %s\n\n" "${local_id[@]}"
        git config --local user.name "${local_id[0]}"
        git config --local user.email "${local_id[1]}"
    fi

    return 0
}

# -------- IMPLEMENTATION
current_remote_url="$(git config --get --local remote.origin.url)"

if [[ "$current_remote_url" ]]; then

    for service in "${git_remotes[@]}"; do

        # Disable case sensitivity for regex matching
        shopt -s nocasematch

        if [[ "$current_remote_url" =~ $service ]]; then
            case "$service" in

                "${git_remotes[0]}" )
                    printf "\n»» An Intermission\n»  %s repository found." "${git_remotes[0]}"
                    setIdentity "${local_id_0[@]}"
                    exit 0
                    ;;

                "${git_remotes[1]}" )
                    printf "\n»» An Intermission\n»  %s repository found." "${git_remotes[1]}"
                    setIdentity "${local_id_1[@]}"
                    exit 0
                    ;;

                * )
                    printf "\n»  pre-commit hook: unknown error\n» Quitting.\n"
                    exit 1
                    ;;

            esac
        fi
    done
else
    printf "\n»» An Intermission\n»  No remote repository set. Using local fallback identity:\n"
    printf "»  User: %s\n»  Mail: %s\n\n" "${local_fallback_id[@]}"

    # Get the user's attention for a second
    sleep 1

    git config --local user.name "${local_fallback_id[0]}"
    git config --local user.email "${local_fallback_id[1]}"
fi

exit 0

แก้ไข:

ดังนั้นฉันจึงเขียน hook เป็น hook และ command ใน Python ใหม่ นอกจากนี้ยังสามารถเรียกสคริปต์เป็นคำสั่ง Git ( git passport) ได้เช่นกัน นอกจากนี้ยังเป็นไปได้ที่จะกำหนดหมายเลข ID โดยพลการภายใน configfile ( ~/.gitpassport) ซึ่งสามารถเลือกได้ในการแจ้งเตือน คุณสามารถค้นหาโครงการที่ github.com: คอมไพล์หนังสือเดินทาง - เป็น Git คำสั่งและตะขอเขียนในหลามในการจัดการหลายบัญชี Git / อัตลักษณ์ของผู้ใช้


1
มันทำงานได้อย่างเรียบร้อย อย่างไรก็ตามมันใช้งานได้ดีกว่าสำหรับฉันด้วยการทำให้เรื่องนี้เป็นเรื่องการชำระเงินภายหลัง (แทนที่จะเป็นข้อผูกมัด) ข้อเสนอแนะของฉันในการปรับปรุงคำตอบนี้ได้รับการกล่าวถึงว่า 1. ข้อมูลโค้ดจะต้องมีการบันทึกไว้เป็น ~ / .git / แม่ / ตะขอ / โพสต์เช็คเอาท์และจะได้รับอนุญาตให้chmod +x post-checkout2. git_remotesค่าเป็นจุดเริ่มต้นในส่วนของชื่อโฮสต์ทั้งหมดเช่นgit@github.com, 3. local_idควรแก้ไขค่าโดยผู้ใช้ตามชื่อและที่อยู่อีเมลที่เกี่ยวข้อง
Shantanu Kumar

@ShantanuKumar ขอบคุณสำหรับความคิดเห็นของคุณ ฉันปรับคำตอบตามที่คุณเสนอ บางทีฉันอาจจะเขียนสคริปต์ใหม่ใน Python เร็ว ๆ นี้
Saucier

เพิ่มการรองรับสำหรับนิพจน์ทั่วไปและที่เก็บข้อมูลที่ไม่มีรีโมต เพื่อง่ายต่อการดาวน์โหลดทั้งหมดรวมที่นี่ Regexps เพื่อแยกแยะ identities สำหรับโครงการต่าง ๆ ในบริการเดียวกัน และการสนับสนุน repos จากระยะไกลด้วยเช่นตัวตนเริ่มต้นทำให้รู้สึกว่าคุณgit initโครงการใหม่จาก IDE เช่นeclipse(ซึ่งไม่สามารถจัดการทริกเกอร์การโต้ตอบแบบ pre-commit) ได้
cfi

25

หากคุณไม่ต้องการมีที่อยู่อีเมลเริ่มต้น ( ลิงก์ที่อยู่อีเมลไปยังผู้ใช้ GitHub ) คุณสามารถกำหนดค่าที่คุณต้องการได้ วิธีที่คุณสามารถทำได้นั้นขึ้นอยู่กับรุ่นของ git ที่คุณใช้ดูด้านล่าง

ข้อเสียเปรียบ (ตั้งใจ) คือคุณต้องกำหนดค่าที่อยู่อีเมลของคุณ (และชื่อของคุณ) หนึ่งครั้งสำหรับทุกที่เก็บ ดังนั้นคุณไม่สามารถลืมที่จะทำ

เวอร์ชัน <2.7.0

[user]
    name = Your name
    email = "(none)"

ในการกำหนดค่าของคุณทั่วโลก~/.gitconfigตามที่ระบุไว้ในความคิดเห็นโดยแดน Aloni ในบล็อกโพสต์ออร์เซลลาของ เมื่อพยายามที่จะคอมมิทครั้งแรกในที่เก็บ, คอมไพล์ล้มเหลวด้วยข้อความดี:

*** Please tell me who you are.

Run

  git config --global user.email "you@example.com"
  git config --global user.name "Your Name"

to set your account's default identity.
Omit --global to set the identity only in this repository.

fatal: unable to auto-detect email address (got '(none)')

ชื่อนี้นำมาจากการกำหนดค่าส่วนกลางเมื่อตั้งค่าที่อยู่อีเมลในเครื่อง (ข้อความไม่ถูกต้องสมบูรณ์)

2.7.0 ≤เวอร์ชัน <2.8.0

พฤติกรรมในรุ่น <2.7.0 ไม่ได้ตั้งใจและแก้ไขด้วย 2.7.0 คุณยังสามารถใช้ก่อนกระทำเบ็ดที่อธิบายไว้ในบล็อกโพสต์ออร์เซลลาของ โซลูชันนี้ใช้ได้กับรุ่นอื่น ๆ ด้วย แต่โซลูชันอื่น ๆ ที่ไม่ใช่สำหรับรุ่นนี้

รุ่น≥ 2.8.0

Dan Aloni เพิ่มตัวเลือกเพื่อให้บรรลุพฤติกรรมดังกล่าว (ดูบันทึกประจำรุ่น ) ใช้กับ:

[user]
    useConfigOnly = true

เพื่อให้ใช้งานได้คุณไม่สามารถให้ชื่อหรือที่อยู่อีเมลในการกำหนดค่าส่วนกลาง จากนั้นในการส่งครั้งแรกคุณจะได้รับข้อความข้อผิดพลาด

fatal: user.useConfigOnly set but no name given

ดังนั้นข้อความจึงไม่ได้ให้คำแนะนำมากนัก แต่เมื่อคุณตั้งค่าตัวเลือกอย่างชัดเจนคุณควรรู้ว่าต้องทำอย่างไร ตรงกันข้ามกับโซลูชันของรุ่น <2.7.0 คุณต้องตั้งค่าทั้งชื่อและอีเมลด้วยตนเอง


ฉันใช้วิธีนี้สองสามเดือนมันใช้งานได้ดี ฉันมีที่อยู่อีเมลหลายแห่ง (ส่วนตัวทำงาน) และฉันไม่ต้องการให้มี "ค่าเริ่มต้น" ที่กำหนดค่าไว้ใน gitconfig ทั่วโลก ด้วยค่าพิเศษ "(ไม่มี)" คอมไพล์จะแจ้งให้ฉันให้ที่อยู่ที่ถูกต้องทุกครั้งที่ฉันหมุน repo ใหม่แทนที่จะคาดเดาหนึ่งตามชื่อผู้ใช้และชื่อโฮสต์ (ซึ่งเป็นที่น่ารำคาญและฉันต้อง - แก้ไขมัน) อย่างไรก็ตามเมื่อเร็ว ๆ นี้ด้วย Git รุ่นอัพเกรด (2.7.0 หรืออาจก่อนหน้านี้) ฉันพบว่าค่าพิเศษ "(ไม่มี)" ไม่ทำให้เกิดข้อผิดพลาดร้ายแรงอีกต่อไป แต่จะใช้ "John Doe <(none)>" ตามที่เป็น ...
Zhuoyun Wei

@wzyboy: โอ้คุณพูดถูก ฉันเคยgit bisectพบที่กระทำ19ce497c ...แนะนำพฤติกรรมนี้ อย่างไรก็ตามเป็นอิสระจากเวอร์ชัน (2.5 - 2.7) ฉันสามารถใช้email =(โดยไม่มีอาร์กิวเมนต์) ในการกำหนดค่าและมันแสดงพฤติกรรมเช่นเดียวกับemail = "(none)"ในเวอร์ชันเก่า คุณยืนยันเรื่องนี้ได้ไหม ถ้าเป็นเช่นนั้นฉันจะแก้ไขคำตอบของฉัน ฉันแค่สงสัยตามที่เห็นได้ชัดและฉันไม่เคยใช้มาก่อน
John

ฉันลองemail =ใน 2.7.0 แล้ว Git ยังคงเดาที่อยู่อีเมลตามชื่อผู้ใช้และชื่อโฮสต์ ตอนนี้ฉันใช้pre-commitวิธีการในบล็อกของ Sella ฉันยังได้แจ้งให้ Dan Aloni ที่มาพร้อมกับ"(none)"ความคิดในโพสต์ของ Sella และเขาได้ทำการแก้ไขเพื่อนำไปใช้เป็นฟีเจอร์อย่างเป็นทางการ: permalink.gmane.org/gmane.comp.version-control.git/285301
Zhuoyun Wei

3
ตั้งแต่ git-2.8: ตัวแปรการกำหนดค่า "user.useConfigOnly" สามารถบังคับให้ผู้ใช้ตั้งค่า user.email & user.name github.com/git/git/blob/master/Documentation/RelNotes/2.8.0 txt
rofrol

@rofrol ขอบคุณสำหรับข้อมูล ฉันปรับปรุงคำตอบของฉันตาม
John

24

ด้วยเงื่อนไขที่รวมอยู่ใน Git 2.13 ตอนนี้เป็นไปได้ที่จะมีผู้ใช้ / อีเมลหลายคนอยู่ร่วมกันในเครื่องเดียวที่มีงานน้อย

user.gitconfigมีชื่อและอีเมลส่วนตัวของฉัน work-user.gitconfigมีชื่องานและอีเมลของฉัน ไฟล์ทั้งสองอยู่ที่~พา ธ

ดังนั้นชื่อ / อีเมลส่วนตัวของฉันจึงถูกนำไปใช้เป็นค่าเริ่มต้น สำหรับc:/work/dir ชื่องาน / อีเมลของฉันจะถูกนำไปใช้ สำหรับc:/work/github/dir จะใช้ชื่อ / อีเมลส่วนตัวของฉัน สิ่งนี้จะทำงานเมื่อการตั้งค่าล่าสุดถูกนำไปใช้

# ~/.gitconfig
[include]
    path = user.gitconfig
[includeIf "gitdir/i:c:/work/"]
    path = work-user.gitconfig
[includeIf "gitdir/i:c:/work/github/"]
    path = user.gitconfig

gitdirเป็นกรณี ๆ ไปและgitdir/iเป็นกรณีตาย

"gitdir/i:github/"จะใช้การรวมเงื่อนไขสำหรับไดเรกทอรีใด ๆ ด้วยgithubในเส้นทาง


ในขณะที่คำตอบของคุณได้รับการชื่นชมและดีTomášJanoušekให้ 20 วันก่อนคุณ โปรดลองลบคำตอบนี้
Hedge

5
@ ป้องกันความเสี่ยงใช่ฉัน upvote คำตอบของเขา แต่ฉันใช้เวลาสักครู่เพื่อกำหนดค่าบน windows และนั่นคือสิ่งที่gitdir/iช่วยฉันออก (ซึ่งคำตอบของเขาไม่ได้พูดถึง)
hIpPy

วิธีเฉพาะ @hIpPy นำสิ่งนี้ไปใช้กับกรณีการใช้งานของฉันโดยตรงและทำให้มันง่ายกว่าการตอบมากกว่า Tomas 'คำตอบ ฉันโหวตทั้งคู่
Isaac Adams

18

ตัวเลือกอื่นในgitการทำงานกับชื่อ / อีเมลหลายรายการคือการใช้นามแฝงgitและใช้การ-cตั้งค่าสถานะเพื่อแทนที่การกำหนดค่าส่วนกลางและที่เก็บเฉพาะ

ตัวอย่างเช่นโดยการกำหนดนามแฝง:

alias git='/usr/bin/git -c user.name="Your name" -c user.email="name@example.com"'

หากต้องการดูว่าใช้งานได้หรือไม่เพียงพิมพ์git config user.email:

$ git config user.email
name@example.com

แทนที่จะนามแฝงคุณยังสามารถใส่ที่กำหนดเองที่ปฏิบัติการภายในของคุณgit$PATH

#!/bin/sh
/usr/bin/git -c user.name="Your name" -c user.email="name@example.com" "$@"

ข้อดีของเมธอดเหล่านี้บนที่เก็บเฉพาะ.git/configคือมันใช้กับทุกที่gitเก็บเมื่อgitโปรแกรมที่กำหนดเองแอ็คทีฟ ด้วยวิธีนี้คุณสามารถสลับระหว่างผู้ใช้ / ชื่อโดยไม่ต้องแก้ไขการกำหนดค่าใด ๆ (ใช้ร่วมกัน)


14

นามแฝง git (และส่วนใน git configs) เพื่อช่วยเหลือ!

เพิ่มนามแฝง (จากบรรทัดคำสั่ง):

git config --global alias.identity '! git config user.name "$(git config user.$1.name)"; git config user.email "$(git config user.$1.email)"; :'

จากนั้นตั้งค่าเช่น

git config --global user.github.name "your github username"
git config --global user.github.email your@github.email

และใน repo ใหม่หรือโคลนคุณสามารถเรียกใช้คำสั่งนี้:

git identity github

โซลูชันนี้ไม่อัตโนมัติ แต่การยกเลิก~/.gitconfigการตั้งค่าผู้ใช้และอีเมลในส่วนกลางของคุณและการตั้งค่าuser.useConfigOnlyเพื่อtrueบังคับให้ git เตือนให้คุณตั้งค่าด้วยตนเองในแต่ละ repo ใหม่หรือที่ลอกแบบมา

git config --global --unset user.name
git config --global --unset user.email
git config --global user.useConfigOnly true

1
ฉันชอบทางออกของคุณ แต่เมื่อฉันยกเลิกการตั้งค่าทั่วโลกของฉันมันก็แค่ทำคอมมิชชันด้วยชื่อโฮสต์ของคอมพิวเตอร์ของฉันแทนที่จะมีคอมไพล์เตือนฉันให้ตั้งใน repo ใด ๆ :(
ENG618

12

นี่คือขั้นตอนที่สมบูรณ์หลังจากอ่านคำตอบมากมายที่นี่

วิธีการตั้งค่าการตั้งค่าหลายคีย์ SSH สำหรับบัญชี Github ที่แตกต่างกัน

คุณอาจต้องการเริ่มตรวจสอบคีย์ที่บันทึกไว้ในปัจจุบันของคุณ

$ ssh-add -l

หากคุณตัดสินใจที่จะลบคีย์แคชทั้งหมดก่อนหน้า ( ไม่บังคับให้เลือกระวังเรื่องนี้ )

$ ssh-add -D

จากนั้นคุณสามารถสร้างคีย์ ssh pub / priv ที่เชื่อมโยงกับอีเมล / บัญชีแต่ละบัญชีที่คุณต้องการ / จำเป็นต้องใช้

$ cd ~/.ssh
$ ssh-keygen -t rsa -C "work@company.com" <-- save it as "id_rsa_work"
$ ssh-keygen -t rsa -C "pers@email.com" <-- save it as "id_rsa_pers"

หลังจากดำเนินการคำสั่งนี้คุณจะได้สร้างไฟล์ต่อไปนี้

~/.ssh/id_rsa_work      
~/.ssh/id_rsa_work.pub

~/.ssh/id_rsa_pers
~/.ssh/id_rsa_pers.pub 

ตรวจสอบให้แน่ใจว่าตัวแทนการตรวจสอบกำลังทำงานอยู่

$ eval `ssh-agent -s`

เพิ่มคีย์ที่สร้างขึ้นดังต่อไปนี้ (จากโฟลเดอร์ ~ / .ssh)

$ ssh-add id_rsa_work
$ ssh-add id_rsa_pers

ตอนนี้คุณสามารถตรวจสอบคีย์ที่บันทึกไว้ได้อีกครั้ง

$ ssh-add -l

ตอนนี้คุณต้องเพิ่มกุญแจสาธารณะที่สร้างขึ้นในเซิร์ฟเวอร์ Acces Keys ของ github / bickbuket ของคุณ

โคลนแต่ละ repos ไปยังโฟลเดอร์ต่าง ๆ

ไปที่โฟลเดอร์ที่ผู้ใช้งานจะทำงานและดำเนินการนี้

$ git config user.name "Working Hard"
$ git config user.email "work@company.com" 

เพียงเพื่อดูว่าสิ่งนี้จะตรวจสอบเนื้อหาของ ".git / config"

ไปที่โฟลเดอร์ที่ใช้persจะทำงานและดำเนินการนี้

$ git config user.name "Personal Account"
$ git config user.email "pers@email.com" 

เพียงเพื่อดูว่าสิ่งนี้จะตรวจสอบเนื้อหาของ ".git / config"

หลังจากทั้งหมดนี้คุณจะสามารถส่งรหัสส่วนตัวและรหัสงานโดยเพียงแค่สลับระหว่างสองโฟลเดอร์

ในกรณีที่คุณใช้ Git Bash และต้องการสร้างคีย์ ssh ใน Windows ให้ทำตามขั้นตอนนี้:

https://support.automaticsync.com/hc/en-us/articles/202357115-Generating-an-SSH-Key-on-Windows


9

มีวิธีแก้ปัญหาง่ายๆที่ดูเหมือนว่าจะทำงานได้ดีสำหรับการหลีกเลี่ยงข้อผิดพลาด

เพียงแค่ลบ[user]ส่วนออกจากของคุณ~/.gitconfigซึ่งจะป้องกันคุณจากการกระทำใด ๆ โดยไม่ต้องตั้งค่าuser.nameสำหรับแต่ละพื้นที่เก็บข้อมูล

ในของคุณ~/.bashrcเพิ่มนามแฝงง่ายๆสำหรับผู้ใช้และอีเมล:

alias ggmail='git config user.name "My Name";git config user.email me@gmail.com'
alias gwork='git config user.name "My Name";git config user.email me@work.job'

สาเหตุที่ไม่ดีคุณจะต้องทำการกำหนดค่าซ้ำในทุก
repit

9

คำตอบนี้ได้รับแรงบันดาลใจบางส่วนจากการโพสต์โดย @Saucier แต่ฉันกำลังมองหาวิธีอัตโนมัติในการตั้งค่าuser.nameและuser.emailบนพื้นฐาน repo ตามระยะไกลซึ่งมีน้ำหนักเบากว่าแพ็คเกจ git-passport ที่เขาพัฒนาเล็กน้อย . ยัง h / t เป็น @John สำหรับการตั้งค่า useConfigOnly นี่คือทางออกของฉัน:

.gitconfig การเปลี่ยนแปลง:

[github]
    name = <github username>
    email = <github email>
[gitlab]
    name = <gitlab username>
    email = <gitlab email>
[init]
    templatedir = ~/.git-templates
[user]
    useConfigOnly = true

ตะขอหลังการชำระเงินซึ่งควรบันทึกลงในเส้นทางต่อไปนี้~/.git-templates/hooks/post-checkout::

#!/usr/bin/env bash

# make regex matching below case insensitive
shopt -s nocasematch

# values in the services array should have a corresponding section in
# .gitconfig where the 'name' and 'email' for that service are specified
remote_url="$( git config --get --local remote.origin.url )"
services=(
    'github'
    'gitlab'
)

set_local_user_config() {
    local service="${1}"
    local config="${2}"
    local service_config="$( git config --get ${service}.${config} )"
    local local_config="$( git config --get --local user.${config} )"

    if [[ "${local_config}" != "${service_config}" ]]; then
        git config --local "user.${config}" "${service_config}"
        echo "repo 'user.${config}' has been set to '${service_config}'"
    fi
}

# if remote_url doesn't contain the any of the values in the services
# array the user name and email will remain unset and the
# user.useConfigOnly = true setting in .gitconfig will prompt for those
# credentials and prevent commits until they are defined
for s in "${services[@]}"; do
    if [[ "${remote_url}" =~ "${s}" ]]; then
        set_local_user_config "${s}" 'name'
        set_local_user_config "${s}" 'email'
        break
    fi
done

ฉันใช้ข้อมูลรับรองที่แตกต่างกันสำหรับ github และ gitlab แต่การอ้างอิงเหล่านั้นในรหัสด้านบนอาจถูกแทนที่หรือเพิ่มเติมด้วยบริการที่คุณใช้ เพื่อให้ตะขอ post-checkout ตั้งชื่อผู้ใช้และอีเมลภายในเครื่องสำหรับ repo โดยอัตโนมัติหลังจากเช็คเอาต์ตรวจสอบให้แน่ใจว่าชื่อบริการปรากฏใน URL ระยะไกลให้เพิ่มลงในอาร์เรย์บริการในpost-checkoutสคริปต์และสร้างส่วนใน ของคุณ.gitconfigที่มีชื่อผู้ใช้และอีเมลสำหรับบริการนั้น

หากไม่มีชื่อบริการปรากฏใน URL ระยะไกลหรือ repo ไม่มีรีโมทชื่อผู้ใช้และอีเมลจะไม่ถูกตั้งค่าในเครื่อง ในกรณีเหล่านี้การuser.useConfigOnlyตั้งค่าจะเล่นซึ่งจะไม่อนุญาตให้คุณกระทำจนกว่าชื่อผู้ใช้และอีเมลจะถูกตั้งค่าที่ระดับ repo และจะแจ้งให้ผู้ใช้กำหนดค่าข้อมูลนั้น


1
ทางออกที่ดี อย่าลืมchmod 755สคริปต์เบ็ด มิฉะนั้นจะถูกคัดลอก แต่ไม่ดำเนินการ
onekiloparsec

5

GIT_AUTHOR_EMAIL + ท้องถิ่น .bashrc

.bashrc_local: อย่าติดตามไฟล์นี้วางไว้ในคอมพิวเตอร์ที่ทำงานของคุณเท่านั้น:

export GIT_AUTHOR_EMAIL='me@work.com'
export GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"

.bashrc: ติดตามไฟล์นี้ทำให้เหมือนกันทั้งในคอมพิวเตอร์ที่ทำงานและที่บ้าน:

F="$HOME/.bashrc_local"
if [ -r "$F" ]; then
    . "$F"
fi

ฉันใช้https://github.com/technicalpickles/homesickเพื่อซิงค์ dotfiles ของฉัน

หาก gitconfig เท่านั้นที่จะยอมรับตัวแปรสภาพแวดล้อม: การขยายตัวแปรเชลล์ในการกำหนดค่า git


5

สภาพแวดล้อมของ Windows

ข้อมูลเพิ่มเติมสามารถแก้ไขได้Git Extensions --> Settings --> Global Settingsหากคุณติดตั้งไว้ในระบบของคุณ

gitextensions ล่าสุดปล่อย

คลิกขวาที่โฟลเดอร์ / ไดเรกทอรีใน Windows Environment เพื่อเข้าถึงการตั้งค่าเหล่านี้ ป้อนคำอธิบายรูปภาพที่นี่

อัปเดต : วิธีสลับ / บำรุงรักษาการตั้งค่าหลายรายการในเวอร์ชัน 2.49 วิธีการสลับ / รักษาการตั้งค่าหลายอย่างในเวอร์ชัน 2.49


ที่อยู่นี้ผู้ใช้หลายคนได้อย่างไรแทนที่จะแก้ไขพวกเขา?

@D_N อัปเดตด้วยภาพหน้าจอใหม่พร้อมตัวเลือกในการเปลี่ยนการตั้งค่า
Abhijeet

เปิดโฟลเดอร์ repo ในพื้นที่แล้วเลือก git-config จากเมนูการนำทางจากนั้นคลิกที่แท็บ Repo ในพื้นที่เนื้อหาจะถูกนำไปใช้กับ $ local_repo_path / .git / config ตามคำตอบด้านบน
maxwu

3

อาจเป็นแฮ็คธรรมดา ๆ แต่ก็มีประโยชน์ เพียงแค่สร้าง 2 คีย์ SSH เช่นด้านล่าง

Generating public/private rsa key pair.
Enter file in which to save the key (/Users/GowthamSai/.ssh/id_rsa): work
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in damsn.
Your public key has been saved in damsn.pub.
The key fingerprint is:
SHA256:CrsKDJWVVek5GTCqmq8/8RnwvAo1G6UOmQFbzddcoAY GowthamSai@Gowtham-MacBook-Air.local
The key's randomart image is:
+---[RSA 4096]----+
|. .oEo+=o+.      |
|.o o+o.o=        |
|o o o.o. +       |
| =.+ .  =        |
|= *+.   S.       |
|o*.++o .         |
|=.oo.+.          |
| +. +.           |
|.o=+.            |
+----[SHA256]-----+

เช่นเดียวกันสร้างอีกหนึ่งสำหรับส่วนบุคคล ดังนั้นคุณมี 2 คีย์ ssh งานและ บริษัท คัดลอก work.pub, ทำงาน, personal.pub, ส่วนตัวไปที่~ / .ssh / Directory

จากนั้นสร้างเชลล์สคริปต์ด้วยบรรทัดต่อไปนี้และตั้งชื่อเป็น crev.sh (Company Reverse) ด้วยเนื้อหาต่อไปนี้

cp ~/.ssh/work ~/.ssh/id_rsa
cp ~/.ssh/work.pub ~/.ssh/id_rsa.pub

เช่นเดียวกันให้สร้าง prev.sh (Personal Reverse) อีกหนึ่งรายการที่มีเนื้อหาดังต่อไปนี้

cp ~/.ssh/personal ~/.ssh/id_rsa
cp ~/.ssh/personal.pub ~/.ssh/id_rsa.pub

ใน ~ / .bashrc เพิ่มนามแฝงสำหรับสคริปต์เหล่านั้นเช่นด้านล่าง

alias crev="sh ~/.ssh/crev.sh"
alias prev="sh ~/.ssh/prev.sh"
source ~/.bashrc

เมื่อใดก็ตามที่คุณต้องการใช้ บริษัท เพียงแค่ทำ crev และถ้าคุณต้องการใช้ส่วนบุคคลทำ prev :-p

เพิ่มคีย์ ssh เหล่านั้นไปยังบัญชี GitHub ของคุณ ตรวจสอบให้แน่ใจว่าคุณไม่ได้สร้าง id_rsa ไว้ก่อนหน้านี้เพราะสคริปต์เหล่านั้นจะเขียนทับ id_rsa หากคุณได้สร้าง id_rsa แล้วให้ใช้สำหรับหนึ่งในบัญชี คัดลอกเป็นส่วนตัวและข้ามการสร้างรหัสส่วนตัว


1

ฉันทำฟังก์ชันทุบตีที่จัดการสิ่งนั้น นี่คือ repo

สำหรับบันทึก:

# Look for closest .gitconfig file in parent directories
# This file will be used as main .gitconfig file.
function __recursive_gitconfig_git {
    gitconfig_file=$(__recursive_gitconfig_closest)
    if [ "$gitconfig_file" != '' ]; then
        home="$(dirname $gitconfig_file)/"
        HOME=$home /usr/bin/git "$@"
    else
        /usr/bin/git "$@"
    fi
}

# Look for closest .gitconfig file in parents directories
function __recursive_gitconfig_closest {
    slashes=${PWD//[^\/]/}
    directory="$PWD"
    for (( n=${#slashes}; n>0; --n ))
    do
        test -e "$directory/.gitconfig" && echo "$directory/.gitconfig" && return 
        directory="$directory/.."
    done
}


alias git='__recursive_gitconfig_git'

1

เพียงเพิ่มส่วนนี้ใน ~ / .bash_profile ของคุณเพื่อสลับระหว่างปุ่มเริ่มต้นสำหรับ github.com

# Git SSH keys swap
alias work_git="ssh-add -D  && ssh-add -K ~/.ssh/id_rsa_work"
alias personal_git="ssh-add -D && ssh-add -K ~/.ssh/id_rsa"

1

นอกจากนี้คุณยังสามารถใช้งานได้git commit --author "Your Name <your@email.com>"ในขณะทำการกระทำใน repo ที่คุณต้องการกระทำเป็นผู้ใช้อื่น


0

คล้ายกับคำตอบของ Rob Wแต่อนุญาตให้ใช้คีย์ ssh ที่แตกต่างกันและทำงานกับเวอร์ชัน git รุ่นเก่า (ซึ่งไม่มีเช่น core.sshCommand config)

ฉันสร้างไฟล์~/bin/git_poweruserโดยได้รับอนุญาตจากผู้ใช้และใน PATH:

#!/bin/bash

TMPDIR=$(mktemp -d)
trap 'rm -rf "$TMPDIR"' EXIT

cat > $TMPDIR/ssh << 'EOF'
#!/bin/bash
ssh -i $HOME/.ssh/poweruserprivatekey $@
EOF

chmod +x $TMPDIR/ssh
export GIT_SSH=$TMPDIR/ssh

git -c user.name="Power User name" -c user.email="power@user.email" $@

เมื่อใดก็ตามที่ฉันต้องการที่จะกระทำหรือผลักดันสิ่งที่เป็น "ผู้ใช้อำนาจ" ผมใช้แทนgit_poweruser gitควรทำงานกับไดเรกทอรีใด ๆ และไม่ต้องการการเปลี่ยนแปลงใน.gitconfigหรือ.ssh/configอย่างน้อยไม่ได้อยู่ในเหมือง


0

แม้ว่าคำถามส่วนใหญ่จะเป็นคำตอบของ OP แต่ฉันก็ต้องผ่านตัวเองและไม่ต้องใช้ googling เลยฉันสามารถหาวิธีแก้ปัญหาที่เร็วและง่ายที่สุดได้ นี่คือขั้นตอนง่าย ๆ :

  • คัดลอกที่มีอยู่.gitconfgจาก repo อื่น ๆ ของคุณ
  • วางลงใน repo ที่เพิ่งเพิ่มเข้าไป
  • เปลี่ยนค่าใน.gitconfigไฟล์เช่นชื่ออีเมลและชื่อผู้ใช้ [user] name = John email = john@email.net username = john133
  • เพิ่มชื่อไฟล์ลงใน.gitignoreรายการเพื่อให้แน่ใจว่าคุณจะไม่ส่ง.gitconfigไฟล์ไปที่ repo ที่ทำงาน
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.