Go on Now Git!

For years I have been trying to force myself to learn and use Git. Maybe the “force” myself is what has prevented me from being successful with the tool. I want to learn Git because the concept intrigues me. In my mind this is a very valid concept to maintain versions of the work I am doing on my local device and in a remote location.

Obviously I have been going about this wrong. I have chosen a direction that clearly does not work for me. In the past I would start a programming project or related project and think, “I need to use Git to maintain versions and to learn the tool while working this project”.

Here is what I think was wrong for me. I need to understand the fundamental concepts behind a tool like this (doesn’t everyone?). In the past, my project was my main focus and what I wanted to complete. So I would do a quick scan over Git commands, maybe watch a couple of YouTube videos and get back to the project. The local repository usually went fine, it was when I engage a remote like Git Hub that things would go south. I would get those git errors, do a Google search for the solution and go down that rabbit hole. Git was not my primary focus, the project was. I would soon realize I was spending too much time fighting git errors and reading Stack Overflow. In my mind I wanted to get the project done, focus on that. Git out of the way Git!

Now I am working on this blog. It is basically something to put on the webserver I described in the post regarding moving a GoDaddy shared host to a Digital Ocean VPS. I do not want to install an FTP server to put files on the server. Pulling from GitHub seems like a good solution and worked during that move. Now that I have the project complete, and Hugo working to convert the markdown files created with Obsidian to a static website, I can now focus on Git.

TL;DR

Quick note on git flow for this blog. Concepts on how it works starts back up with the Fundamental Concepts section.

Local Repository

Go to the hugo public directory to post the updated html on the remote

  • check that you have the latest update from remote
 git pull
 git status

modify the post files and update using hugo when complete

git add.
git commit -m "description of modification"

then update remote

git push

Webserver update

access the webserver via ssh

ssh 09flhrc

navigate to the blog directory

cd /var/www/html/tipnmogblog

pull the code from the remote

sudo git pull

Fundamental Concepts

After Git is installed. The git config needs to be setup so that the user information can be stored so that when commits are made, the user who made those updates will be identified.

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

Local Repository

Create local repository

After creating the folder where you will be storing and working on your project you will initialize the git repository

git init

A hidden folder will be created to store the local repository where the git history and snapshots from commits will be stored. Git can now start capturing changes to the files in the folder.

The git history will be stored in branches which can be split off for things like revisions and features while the stable code can be kept in a master branch. This is usually where things would start to go wrong for me because of the branches and for me not realizing what branch I was in.

Branches

If you read documentation or review video for Git concepts dating back a few years ago, you will learn that the branch for the code history will be stored in the “master” branch. If a revision is to be made, you would check out a new branch with your name selection to store the revision updates while the stable code could would stay in master. In 2020 many remote repositories like GitHub changed the name of that branch to “main” in order to be more inclusive.

For whatever reason, when my device set up a local repository it would name the branch “master” I would do the git thing and try to push to the GitHub remote repository which would default to “main” branch.

To see what branch you are on you can use the status command

git status

branch name will be shown at the top of response

Rename Branch

To rename the branch i.e. master to main

git branch -m "main"

-m = move, -M = force move

your can also update the local branch name default in git config

The Three Stages of a Git Repository

  • Working Directory (or Working Tree)
    • This is the local directory on your computer where you create, edit, and delete files.
    • Files here are in a “modified” or “untracked” state.
    • Changes in this area are not yet being tracked for the next commit snapshot.
  • Staging Area (or Index)
    • The staging area acts as a “draft board” or intermediate area where you gather specific changes you want to include in your next commit.
    • You use the git add command to move files or specific changes from the working directory to the staging area. This allows you to selectively stage only certain modifications, even within a single file.
    • Files in this area are in a “staged” state.
  • Local Repository
    • This is where Git permanently stores the project’s history as a series of snapshots (commits).
    • When you use the git commit command, Git takes all the files currently in the staging area and saves that precise snapshot into the local repository.
    • Files in this area are in a “committed” state. 

The Basic Git Workflow

The typical process for managing changes in Git follows this cycle:

  1. Use git init to set up the repository in the working directory.
  2. Modify files in your working directory.
  3. Use the git add command to move specific changes to the staging area.
  4. Use the git commit command to record the staged changes as a permanent snapshot in the local repository history.
  5. Optionally, use the git push command to upload the commits from your local repository to a remote repository like GitHub.

Add add files to be tracked by git

git add .

will add all files in the working directory.

git add file.name

will add a single file by name to staging.

Commit record staged changes to repository history.

git commit -m "description of revision"

Remote Repository

A remote URL is Git’s fancy way of saying “the place where your code is stored.” That URL could be your repository on GitHub, or another user’s fork, or even on a completely different server.

You can only push to two types of URL addresses:

  • An HTTPS URL like https://github.com/user/repo.git
  • An SSH URL, like git@github.com:user/repo.git

Git associates a remote URL with a name, and your default remote is usually called origin.

Creating remote repositories

You can use the git remote add command to match a remote URL with a name. For example, you’d type the following in the command line:

git remote add origin <REMOTE_URL>

This associates the name origin with the REMOTE_URL.

You can use the command git remote set-url to  change a remote’s URL

Showing Your Remotes

To see which remote servers you have configured, you can run the git remote command. It lists the shortnames of each remote handle you’ve specified. If you’ve cloned your repository, you should at least see origin — that is the default name Git gives to the server you cloned from:

$ git clone https://github.com/schacon/ticgit
Cloning into 'ticgit'...
remote: Reusing existing pack: 1857, done.
remote: Total 1857 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (1857/1857), 374.35 KiB | 268.00 KiB/s, done.
Resolving deltas: 100% (772/772), done.
Checking connectivity... done.
$ cd ticgit
$ git remote
origin

You can also specify -v, which shows you the URLs that Git has stored for the shortname to be used when reading and writing to that remote:

$ git remote -v
origin	https://github.com/schacon/ticgit (fetch)
origin	https://github.com/schacon/ticgit (push)

If you have more than one remote, the command lists them all. For example, a repository with multiple remotes for working with several collaborators might look something like this.

$ cd grit
$ git remote -v
bakkdoor  https://github.com/bakkdoor/grit (fetch)
bakkdoor  https://github.com/bakkdoor/grit (push)
cho45     https://github.com/cho45/grit (fetch)
cho45     https://github.com/cho45/grit (push)
defunkt   https://github.com/defunkt/grit (fetch)
defunkt   https://github.com/defunkt/grit (push)
koke      git://github.com/koke/grit.git (fetch)
koke      git://github.com/koke/grit.git (push)
origin    git@github.com:mojombo/grit.git (fetch)
origin    git@github.com:mojombo/grit.git (push)

This means we can pull contributions from any of these users pretty easily. We may additionally have permission to push to one or more of these, though we can’t tell that here.

Adding Remote Repositories

We’ve mentioned and given some demonstrations of how the git clone command implicitly adds the origin remote for you. Here’s how to add a new remote explicitly. To add a new remote Git repository as a shortname you can reference easily, run git remote add <shortname> <url>:

$ git remote
origin
$ git remote add pb https://github.com/paulboone/ticgit
$ git remote -v
origin	https://github.com/schacon/ticgit (fetch)
origin	https://github.com/schacon/ticgit (push)
pb	https://github.com/paulboone/ticgit (fetch)
pb	https://github.com/paulboone/ticgit (push)

Now you can use the string pb on the command line in lieu of the whole URL. For example, if you want to fetch all the information that Paul has but that you don’t yet have in your repository, you can run git fetch pb:

$ git fetch pb
remote: Counting objects: 43, done.
remote: Compressing objects: 100% (36/36), done.
remote: Total 43 (delta 10), reused 31 (delta 5)
Unpacking objects: 100% (43/43), done.
From https://github.com/paulboone/ticgit
 * [new branch]      master     -> pb/master
 * [new branch]      ticgit     -> pb/ticgit

Paul’s master branch is now accessible locally as pb/master — you can merge it into one of your branches, or you can check out a local branch at that point if you want to inspect it.

Fetching and Pulling from Your Remotes

To get data from your remote projects, you can run:

$ git fetch <remote>

The command goes out to that remote project and pulls down all the data from that remote project that you don’t have yet. After you do this, you should have references to all the branches from that remote, which you can merge in or inspect at any time.

If you clone a repository, the command automatically adds that remote repository under the name “origin”. So, git fetch origin fetches any new work that has been pushed to that server since you cloned (or last fetched from) it. It’s important to note that the git fetch command only downloads the data to your local repository — it doesn’t automatically merge it with any of your work or modify what you’re currently working on. You have to merge it manually into your work when you’re ready.

If your current branch is set up to track a remote branch, you can use the git pull command to automatically fetch and then merge that remote branch into your current branch. This may be an easier or more comfortable workflow for you; and by default, the git clone command automatically sets up your local master branch to track the remote master branch (or whatever the default branch is called) on the server you cloned from. Running git pull generally fetches data from the server you originally cloned from and automatically tries to merge it into the code you’re currently working on.

Note From git version 2.27 onward, git pull will give a warning if the pull.rebase variable is not set. Git will keep warning you until you set the variable.If you want the default behavior of git (fast-forward if possible, else create a merge commit): git config --global pull.rebase "false"If you want to rebase when pulling: git config --global pull.rebase "true"

Pushing to Remotes

When you have your project at a point that you want to share, you have to push it upstream. The command for this is simple: git push <remote> <branch>. If you want to push your master branch to your origin server (again, cloning generally sets up both of those names for you automatically), then you can run this to push any commits you’ve done back up to the server:

$ git push origin master

This command works only if you cloned from a server to which you have write access and if nobody has pushed in the meantime. If you and someone else clone at the same time and they push upstream and then you push upstream, your push will rightly be rejected. You’ll have to fetch their work first and incorporate it into yours before you’ll be allowed to push.

Inspecting a Remote

If you want to see more information about a particular remote, you can use the git remote show <remote> command. If you run this command with a particular shortname, such as origin, you get something like this:

$ git remote show origin
* remote origin
  Fetch URL: https://github.com/schacon/ticgit
  Push  URL: https://github.com/schacon/ticgit
  HEAD branch: master
  Remote branches:
    master                               tracked
    dev-branch                           tracked
  Local branch configured for 'git pull':
    master merges with remote master
  Local ref configured for 'git push':
    master pushes to master (up to date)

It lists the URL for the remote repository as well as the tracking branch information. The command helpfully tells you that if you’re on the master branch and you run git pull, it will automatically merge the remote’s master branch into the local one after it has been fetched. It also lists all the remote references it has pulled down.

That is a simple example you’re likely to encounter. When you’re using Git more heavily, however, you may see much more information from git remote show:

$ git remote show origin
* remote origin
  URL: https://github.com/my-org/complex-project
  Fetch URL: https://github.com/my-org/complex-project
  Push  URL: https://github.com/my-org/complex-project
  HEAD branch: master
  Remote branches:
    master                           tracked
    dev-branch                       tracked
    markdown-strip                   tracked
    issue-43                         new (next fetch will store in remotes/origin)
    issue-45                         new (next fetch will store in remotes/origin)
    refs/remotes/origin/issue-11     stale (use 'git remote prune' to remove)
  Local branches configured for 'git pull':
    dev-branch merges with remote dev-branch
    master     merges with remote master
  Local refs configured for 'git push':
    dev-branch                     pushes to dev-branch                     (up to date)
    markdown-strip                 pushes to markdown-strip                 (up to date)
    master                         pushes to master                         (up to date)

This command shows which branch is automatically pushed to when you run git push while on certain branches. It also shows you which remote branches on the server you don’t yet have, which remote branches you have that have been removed from the server, and multiple local branches that are able to merge automatically with their remote-tracking branch when you run git pull.

Renaming and Removing Remotes

You can run git remote rename to change a remote’s shortname. For instance, if you want to rename pb to paul, you can do so with git remote rename:

$ git remote rename pb paul
$ git remote
origin
paul

It’s worth mentioning that this changes all your remote-tracking branch names, too. What used to be referenced at pb/master is now at paul/master.

If you want to remove a remote for some reason — you’ve moved the server or are no longer using a particular mirror, or perhaps a contributor isn’t contributing anymore — you can either use git remote remove or git remote rm:

$ git remote remove paul
$ git remote
origin

Once you delete the reference to a remote this way, all remote-tracking branches and configuration settings associated with that remote are also deleted.

Git Notes

see git config

git config --list

initialize

git init

Check status and see what branch you are on

git status

Rename the branch using the move option (-m):

git branch -m <new-name>

add files to staging

git add .

you can also add just a file

git add file.txt

push local commit to remote (Github)

git remote -v
git remote add origin https://github.com/tipnmog/tipnmogblog.git
git branch -M main
git push -u origin main

Steps to Remove the Origin Remote

  1. Open your terminal or command prompt and navigate to your local Git repository’s directory.

  2. Verify the current remotes configured for your repository by running:

    bash

    git remote -v
    

    This command lists the names and URLs for the fetch and push operations of your remotes, e.g., origin https://github.com (fetch).

  3. Remove the origin remote by using one of the following commands:

    • bash

      git remote remove origin
      
    • bash

      git remote rm origin
      

    The remove form is generally preferred, but rm is a valid alias.

  4. Verify the removal by running git remote -v again. The origin remote should no longer appear in the list. 

After Removal

  • If you need to connect your local repository to a different remote URL, you can add a new remote using the git remote add command:

    bash

    git remote add origin [new_url]
    
  • Alternatively, you can change the existing remote URL without removing it first by using git remote set-url:

    bash

    git remote set-url origin [new_url]
    
  • To delete a branch on the remote server (not the remote connection itself), you would use a different command:

    bash

    git push origin --delete [branch_name]
    

    Note that this is different from removing the remote configuration for “origin”