Petra Rabbit is a developer. She would like to contribute to some private repositories that Zach Cat has set up on BitBucket and GitHub.

1. Using SSH to clone a repository on BitBucket

Zach has a private repository on BitBucket called “X_Files” that Petra needs to clone locally:

$ git clone git@bitbucket.org:zach-the-cat/x_files.git
Cloning into 'x_files'...
The authenticity of host 'bitbucket.org (104.192.141.1)' can't be established.
RSA key fingerprint is SHA256:zzXQOXSRBEiUtuE8AikJYKwbHaxvSc0ojez9YXaGp1A.
Are you sure you want to continue connecting (yes/no/[fingerprint])? 
Warning: Permanently added 'bitbucket.org' (RSA) to the list of known hosts.

This is the first time Petra has used SSH to talk to the BitBucket server on this computer. Consequently, she sees that prompt from SSH asking her if it is okay to add the server IP address to its list of known hosts.

yes
Warning: Permanently added 'bitbucket.org' (RSA) to the list of known hosts.
Forbidden
fatal: Could not read from remote repository.
Please make sure you have the correct access rights and the repository exists.

Yeah… it’s just not that easy. In order for this to happen:

  • Petra has to create a user account on BitBucket;
  • Zach has to grant Petra’s BitBucket user account read+write permission on his repository;
  • Petra has to create a public+private RSA key pair for her development laptop
  • She has to upload the public key to her BitBucket account

Zach goes to BitBucket > X_Files > Repository Settings > User and Group Access, and searches for Petra by email address; selects WRITE access; and confirms.

And now Petra sees an email from Atlassian, “Zach The Cat invited you to collaborate on the X_Files repository on BitBucket”. Of course, she accepts the invitation… When she logs in to BitBucket in her browser, she can now see Zach’s repo. Try again, Petra:

$ git clone git@bitbucket.org:zach-the-cat/x_files.git
Cloning into 'x_files'...
git@bitbucket.org: Permission denied (publickey).
fatal: Could not read from remote repository.
Please make sure you have the correct access rights and the repository exists.

Well, at least it’s a different error, because she’s not quite done yet: She has to create an RSA key pair identifying her on her development laptop, and upload the public key to her account on BitBucket:

$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/petra/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): *********
Enter same passphrase again: *********
Your identification has been saved in /home/petra/.ssh/id_rsa
Your public key has been saved in /home/petra/.ssh/id_rsa.pub

She was prompted to enter a passphrase, and she’s going to need it every time she talks to the remote repository, so let’s hope she picked something memorable!

Now Petra goes to BitBucket > Profile and Settings > Personal settings > SSH Keys. It says “There are no keys configured” but she can click on the Add Key button, and paste the contents of the id_rsa.pub file, along with a descriptive label. The label could be any text but it helps to use something that identifies the current user and client computer (i.e. the development machine), because if she switches machines (i.e. uses a virtual machine or another laptop) then She’ll need to upload a separate public key for that environment also.

Having uploaded the public key to BitBucket, and with the private key accessible to SSH locally, Petra should now be able to clone the repository successfully:

$ git clone git@bitbucket.org:zach-the-cat/x_files.git
Cloning into 'x_files'...

At this point she’s prompted to enter her passphrase for the RSA key pair, and does so.

remote: Enumerating objects: 13, done.
remote: Counting objects: 100% (13/13), done.
remote: Compressing objects: 100% (12/12), done.
remote: Total 13 (delta 2), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (13/13), done.
Resolving deltas: 100% (2/2), done.

Let’s review:

$ ls -l
total 4
drwxrwxr-x 3 petra petra 4096 Sep 10 11:48 x_files
$ cd x_files
$ git status
On branch main
Your branch is up to date with 'origin/main'.
nothing to commit, working tree 

Git Passphrase Persistence

Petra may get prompted for her RSA key pass phrase every time she commits a change, or fetches changes, but a Git Bash session can run an agent process that takes care of this for her. It is per-session – during the remainder of that session, she won’t get prompted for the pass phrase, except for one time while setting up the agent:

$ eval $(ssh-agent)
Agent pid 227166
$ ssh-add ~/.ssh/id_rsa
Enter passphrase for /home/petra/.ssh/id_rsa: *************
Identity added: /home/petra/.ssh/id_rsa (petra@mcgregor_garden)

For further reading: https://smallstep.com/blog/ssh-agent-explained/

Differences between Windows and Linux

If you use the Git Bash console on Windows, then the workflow is almost exactly the same as that described above. The only difference is that the RSA key files are located in C:\Users\<user>\.ssh\

If you don’t use Git Bash or ssh-keygen, then there are tutorials out there on how to use PuTTYgen or OpenSSH.

2. Using HTTPS to clone a private repository on BitBucket

Petra Rabbit experiments with using HTTPS instead. Typically BitBucket or GitHub will tell us that the Git URL to use with HTTPS is:

https://user-name@bitbucket.org/user-name/repo-name.git

It’s easy to forget that the first user-name is the user we are authenticating as, and the second user is the owner of the repository. So, Petra needs to use her BitBucket account name in place of the first, authenticating user:

$ git clone https://petra-rabbit@bitbucket.org/zach-the-cat/x_files.git
Cloning into 'x_files'...
Password for 'https://petra-rabbit@bitbucket.org': *******
Unpacking objects: 100% (13/13), 2.65 KiB | 677.00 KiB/s, done.

BitBucket accepts her “petra-rabbit” account password.

3. Using HTTPS to clone a repository on GitHub

Petra has created her own private repository on GitHub called “Y_Files” and she’d like to clone it locally so that she can develop offline. GitHub tells her the URL to use for HTTPS:

https://github.com/petra-rabbit/Y_Files.git

It’s interesting that it is different from the URL that BitBucket suggests, it’s missing the “user-name@” prefix. No problem, it will just prompt for a user name:

$ git clone https://github.com/petra-rabbit/Y_Files.git
Cloning into 'Y_Files'...
Username for 'https://github.com': petra-rabbit
Password for 'https://petra-rabbit@github.com': ********
remote: Support for password authentication was removed on August 13, 2021. Please use a personal access token instead.
remote: Please see https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/ for more information.
fatal: Authentication failed for 'https://github.com/petra-rabbit/Y_Files.git/'

Interesting. GitHub is going to require Petra to learn about Personal Access Tokens:
https://docs.github.com/en/github/authenticating-to-github/keeping-your-account-and-data-secure/creating-a-personal-access-token

Petra opens GitHub in her web browser and navigates to: GitHub Profile > Settings > Developer Settings > Personal access tokens.

She clicks on Generate New Token.; ticks the [x] repo checkbox; generates the token; and saves it in a text file in a secret location.

Try again, this time including the user-name prefix, just to prove it works:

$ git clone https://petra-rabbit@github.com/petra-rabbit/Y_Files.git
Cloning into 'Y_Files'...
Password for 'https://petra-rabbit@github.com': 

This time, instead of her GitHub account password, Petra pastes the PAT string:

Password for 'https://petra-rabbit@github.com': ********************************
remote: Enumerating objects: 9, done.
remote: Counting objects: 100% (9/9), done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 9 (delta 1), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (9/9), 1.95 KiB | 664.00 KiB/s, done.

Repository successfully cloned locally:

$ cd Y_Files
$ git status
On branch main
Your branch is up to date with 'origin/main'.
nothing to commit, working tree clean

Sorted.

4. Granting permission to other developers in GitHub

Petra would like to invite Zach The Cat to contribute to her Y_Files repo on GitHub.

  • She navigates to GitHub > Repositories > Y_Files > Settings > Manage Access
  • She presses the Invite a collaborator button
  • She searches for the user zach-the-cat, selects him, and waits.
  • Zach receives an invitation via email and accepts.
  • Petra’s Y_Files repository now has one collaborator

Exercise for the Student: Save your Git repository remote authentication credentials in your favorite IDE.

That’s all for this Appendix. Go back to the Top.