Friday, May 17, 2024

Git and Github: Crash Course

Hello again--this post isn't about audio, hardware, MPUs, soldering, DACs, or even electronics tools like EDA's and scopes.

Instead, I present my lab notes: how I have configured GIT/github, a popular version control system, for my various development computers. Excitement.

Why the kitten with the octopus tentacle?




Intro: WHY USE A VCS?


Even a small potatoes software developer like me needs version control. 

Before using GIT for version control I wasted a lot of time screwing up/making working the code worse, then spending hours cursing while I got the code back to a point where it functioned.

Before breaking my code, did I save a copy first?  

Nope. 

Enough! 

I have been a big advocate of VCS's since the early 2000's (Gnu CVS).

Nowadays I use Git, but don't use it often enough to remember the anything beyond the basics--that's why we use AI, I mean: that's why we write things down.

If you are a beginning programmer and want to learn a bit more about this free VCS--"version control system"--Git is the most popular VCS nowadays--this content might be of interest.  

If you know GIT better than I do--I only know and use maybe 5% (?) of its commands--you're probably going to want to skip this one. EVEN BETTER: if you are an experienced Git user, please read this post; where you find it oversimplified, misleading, or incorrect, please comment so I can improve and better learn GIT.

WHEN U ASSUME?


Assumptions:
  • Your development computer has GIT installed--if not installation details are here.
  • You have some previous experience with version control software or at least knows what it's used for/why it's important.
  • You have a user identity already set up on Github (mine is "cslammy"; yours isn't)--if not, get one; New user creation is well documented--go here.
  • You use SSH to securely communicate between your dev system(s) and Github--there are other ways to do this, but I know SSH pretty well so it's what I use and what's covered in this post. 
  • You are setting the whole thing up "from scratch", otherwise, if your SSH keys are already set up, skip that step below.


FIRST STEP: CREATE NEW REPO ON GITHUB

Log into github.com with your assigned username.

Click on the repositories tab at the top

Create a new repository. 

IMPORTANT FOR SECURITY: choose "private" if you have any keys in your code...for instance, an API key. I created a new a repo that was public but had a private key in it in clear text.  Fortunately an admin from github saw this and shut down the repo, then, emailed me to tell me about my mistake.  

I had to delete the repo, change the key, and start the whole process over.  You don't want to have to do this, so, be careful.

Do not add files, license info, readmes, etc., to the repo at this time.

NEXT: SETTING UP SSH


============CREATING PASSWORDLESS SSH=========== 
 

On your development PC(s) install OPENSSL if needed.

For UBUNTU desktop (I use 22.04 currently), openssl was already installed; nothing to do. If not? different distros have different installation steps. As a Ubuntu/Debian/Mint guy, for me it would be something like this.

For Windows: get cygwin64, install using defaults, and add C:\cygwin64\bin to %PATH%. This will allow opensll (needed for keygen) to run from Windows command line ("cmd"). Step by step instructions are here.

===========SSH PRIVATE AND PUBLIC KEYS===========

For a machine to talk to github using SSH you have to create SSH keys, store the private key locally, and upload the public key to github; details here.

The following command creates a public/private key pair in ~/.ssh on linux; the same command works for cygwin Windows:
 
ssh-keygen -t ed25519 -C [github assigned email address]

so for me:  

ssh-keygen -t ed25519 -C cslammy@github.com

note: use the default name suggested by your OS for your public/private keypair. If you rename your keypair your secure connection to github may never be established, or, may break.

note: rename ed25519 and ed25519.pub if they already exist.cat

note: why "cslammy@github.com"? Why not the gmail email address I associated with my github.com account when I first created an account?

It's the way Github works: each user gets a github.com email address when they join github.

This Github assigned email is used for SSH key management; you use git@github.com in the git CLI for ssh remote, but you use your personal email address (e.g.: foobar42@gmail.com) for other github related things, like getting emails from the github community.  

These 3 different logins/identities confused me at first....it made more sense after I used git and github for awhile.  

Like it or not, you will need all 3.
 
========POTENTIAL LINUX GOTCHA?=========

Check that the generated keys are copied to ~/.ssh by default.

On one of my ubuntu hosts I saw that the keys were not stored in ~/.ssh directory. 

or maybe I didn't choose to save to default location?

As far as I can tell, the keys (at least private?) need to be in ~/.ssh or SSH to github will not work!!

If they are not there:
  • Figure out where the keys got stored (maybe in your home directory?)
  • Note existing CHMOD's/CHOWN's for private and public keys
  • Copy keys to ~/.ssh directory
  • If needed, CHMOD and CHOWN copied files/folders to match originals.

===========UPLOAD PUBLIC KEYS TO GITHUB===========
 
On the dev system's ~/.ssh folder that has the private key there will be a public key; its filename ends in .pub.
  • Cat the .pub file or in Windows open it in Notepad.
  • Copy the .pub text content without any spaces, extra lines, etc. to your clipboard.
The public key will look something like what you see below, which is an example, not a real public key:

ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAFBAAIFo+Zumzwrm/DsmDqJCZLJQQmr4CA5Qhgb2TyxI1gtqX cslammy@github.com

Then:
  • Go to github.com, log in
  • Click on your profile icon in the top right of the main page.
  • Go to settings > ssh and gpg keys > ssh tab
  • Upload the SSH public key text to github (more here).
NOTE: as far as I can tell, the public keys uploaded to github don't stick around forever. You may need to re-upload your public keys from time to time.

============ADD GITHUB TO KNOWN HOSTS============

I have only seen this on Linux, and only occasionally,

ssh-keyscan github.com >> ~/.ssh/known_hosts #Not sure this was needed

Did it work?
➜ .ssh more config
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_rsa
 
Was/is this is step needed? Probably not.

=========TEST WITH SSH===========

From a system that has the required private key etc.

ssh -T git@github.com

Note you use git@github.com as username/domain, NOT your git username (for me, cslammy....) 
(or)

ssh -Tv git@github.com #includes verbose debug info.

If if works, you should see something like this:

Hi cslammy! You've successfully authenticated, but GitHub does not provide shell access.

NOTE: Again, you must use git@github.com<mailto:git@github.com> when testing SSH protocol to github. Not some other username. 


SETTING UP THE REST


=========GIT CONFIG ON YOUR PC=========

Git has a lot of configuration options.

One is to make sure to set: that the default Git branch is “main” locally.  That will match github.com’s default. 

You have to change this for at least some Linux distros--local default branch for Ubuntu git for me last time i set up git/Github was “master” which did not match the current Github default.

On linux or Windows, from terminal:

git config --global init.defaultBranch main

From:

Next, set how carriage returns are handled for your OS--different for Windows OS vs. Linux....details here.

For Linux development systems: 
git config --global core.autocrlf input

For Windows development systems: 
git config --global core.autocrlf true

Next, choose VSCODE as your editor for things like git commits: 
 
git config --global core.editor "code --wait" 

Finally: consider setting the rest of the default features described here; kitchen sink details are here.

========GET THE URL OF THE NEW REPO==========

Create new github repository at the public github website (how-to is here).  
**DO NOT ADD ANY CONTENT YET**
  • There is a green button called CODE in the new repository
  • There is choice for what to display: SSH or HTML.
  • click on SSH
  • You will see a URL looking string to use for SSH to this new repro; here is an example.
git@github.com:cslammy/AD9833VCO.git 

Copy this to clipboard, save it to Word, save it to notepad++, whatever.  
You will need this again shortly.

==========LOCAL DIR AND GIT INIT=======

Create new directory on local Linux or windiows machine for the new project.

(or)

CD to an existing directory where you already have some code.
 
issue this command:

git init

This creates .gitignore, DB files etc, for any data in the directory.

Note: if you want to get rid of git for the project (Linux):
  • go to the root directory for your project
  • ls -la
  • delete the .git directory:  rm -rF .git
=====EDIT YOUR .GITIGNORE FILE ==========

.gitignore basics are here

.Gitignore is a text file that tells Git what files and folders you don't want to version control. 

You will probably want to modify .gitignore for each project you version control--otherwise a whole buncha crap of you don't want to replicate will replicate (such as a "build" folder and all its contents, created by cmake).  Doh!

A pretty typical .gitignore file for me, for VSCODE/CMAKE coding, that seems to work, has only 3 lines:

Deprecated
deprecated
build 


Deprecated is where I put anything no longer salient to the project; docs are things like PDFs of IC's used. Whatever. Up to you.

============SETTING UP PUSHES AND PULLS==========

Now that we have the above steps, next, let's set up the commands we will use to securely send and receive data to github...we are not doing the actual push yet, rather, configuring git locally so we can push and pull data later.

To do pushes and pulls git uses commands like this:

git push [variable] [branch]
git pull [variable] [branch]

First, think of a variable name, a common one in our situation is "origin"

Make sure your variable isn't already set. If it is, you want to get rid of it.

DANGER! Failing to do this can lead to all sorts of problems.  

open terminal and CD to your project's directory.  Then run this.

git remote -v

if you already see an "origin main" pointing to a different repo, you need to get rid of it (or choose another variable).

git remote rm origin  #remove "origin" as variable.

Then, set a git variable to represent the remote repository. You can reuse origin.
 
Here is an example:

git remote add origin git@github.com:cslammy/AD9833VCO.git
 

[Branch] is the info you wrote down or copied into clipboard or notepad....will look something like this:

git@github.com:cslammy/AD9833VCO.git 


...where AD9833VCO.git is the name of a repo folder you want to push to.


 
======README AND LICENSE=========

Optional, but I do it: on the local system, for public repos, create a README.md and a License file. 

Then:

=====DO AN INITIAL PUSH OF FILES FROM GITHUB TO LOCAL====
 
Assuming I already have some code in my project folder, I do a git push first.

Git needs to know about your work so far...git status says what needs to get uploaded; git add . adds everything except gitignore files and folders to the queue, and git commit gets everything packed up and ready to go:

cd to your project directory if you aren't already there, then:

git status
git add .
git commit -m "initial upload"

Then, use this to push files for the first time to github.

git push -f origin main
 
After successful push you will see your local files in your new repo online. 

And...if it worked, you will see something like this:
 
git:(main) git push origin main
Warning: Permanently added the ECDSA host key for IP address 'x.x.x.x' to the list of known hosts.
Enumerating objects: 13, done.
Counting objects: 100% (13/13), done.
Compressing objects: 100% (12/12), done.
Writing objects: 100% (13/13), 6.52 KiB | 667.00 KiB/s, done.
Total 13 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2), done.
To github.com:cslammy/SYNTH.git

You now have version control working and your precious code in more than one storage repo. 

SUCCESS!

========PULLING DATA from github to local============

For whatever reason you added or changed data on the github repo using your web browser; now, you want to pull those changes back to your local dev system.

git pull origin main  #pull repo adds/changes to local dev system
git config pull.rebase false  #make the local DB whole by merging it                                 #with remote db.


========ESSENTIAL COMMANDS FOR VERSIONING=======

Once your git/Github setup works you can use the gazillion other commands (reference is here).

Obviously I won't go into all of it here--just the basics, ma'am.

A good command to see what changes you have made since the last commit:

git diff

OK, you've made some code changes, now you want to get save your changes as a new version.

git status
git add .
git commit –m “added foobar function to main.c”  

If you just say 
git status
git add .
git commit

your commit notes will be editable in your text editor--which you can configure using git config, how to do this is here.

Finally push the changes up to the cloud:

git push origin main


 ======GOING BACK TO PREVIOUS SAVED VERSIONS=====

git log

this shows the messages you tagged to each commit and its commit ID 

Once you have locked in on the ID you want to roll back to, here is the command to roll things back.

git reset --hard 0ad5a7a69ab9240da

=====DIFF CURRENT CODE AND LAST COMMIT===========

I use this all the time, useful not just for version control but to see your last bread crumb trail

git diff


OUTTRO


Wow already a long post, and this post only covers extreme GIT basics.
 
I will be adding to/correcting/updating this post as time goes on and I have git projects in front of me. 
I am revising code for a RP2040 clock multiplier, that will have a fair amount of embedded C and need a gitload of work. 

Will it work? Who knows?  Hopefully more about that project in the next few posts.

No comments:

Post a Comment

Rotary Encoder Expermenter's Board: Improving the Hardware

Quick one this time....I have posted a few projects lately that incorporated a Raspberry Pi Pico, rotary encoder, and .96" OLED:  here ...