Notes: Git & GitHub: In project with main branch deployed to hosting site, using newfeature git branch for development and eventual merging into main branch

Last updated on 4 Jul. 2024

Quick Info

To create a development branch called xyz-feat and set it as current branch:
  • git branch xyz-feat
  • git checkout xyz-feat
To stage and commit changes to local xyz-feat branch, first ensure that xyz-feat is current branch. Then:
  • git add .
  • git commit -m "[msg]"
For Github repo already set with remote main branch mapped to local git main branch (as is the usual case), use following command to create xyz-feat branch in Github and push local files of xyz-feat to Github xyz-feat branch.:
  • git push origin xyz-feat
To push later changes from xyz-feat local git branch to Github xyz-feat branch:
  • git push origin xyz-feat
To merge xyz-newfeat into main and push to remote:
  • git checkout main
  • git merge xyz-newfeat
  • git push
To delete xyz-newfeat (after merge):
  • git branch -d xyz-newfeat
  • git push -d origin xyz-newfeat

Details

In the very simple gita app that I am working on now, as updates on its main branch on GitHub are set to automatically get deployed on Vercel, I wanted to do some development work (Go to chapter verse component) in a separate development branch where I could commit intermediate stage changes without it getting deployed to live site on Vercel. That needed me to get into branch stuff in git and GitHub. Given below are notes from that learning:

https://www.atlassian.com/git/tutorials/using-branches seems to be a very interesting page explaining utility of branches and how to create and merge branches.

'git branch' - Lists branches. VSCode shows current branch in bluish-green colour and with an * before it.
'git branch <branch-name>' - Creates a new branch called <branch-name>
'git branch -d' - Deletes a branch
'git checkout <branch-name>' - Switches to (existing branch) <branch-name>. Head points to <branch-name>. VSCode gives a message "Switched to branch '<branch-name>'". VSCode shows file contents as in that branch.
'git checkout -b <branch-name>' - Creates a new branch called <branch-name> and switches to it. Head points to <branch-name>

To create a development branch called xyz-feat and set it as current branch:
git branch xyz-feat
git checkout xyz-feat

For Github repo already set with remote main branch mapped to local git main branch (as is the usual case), use following command to create xyz-feat branch in Github and push local files of xyz-feat to Github xyz-feat branch.:
git push origin xyz-feat

Creating branches in git: section "How to Create a Branch" in https://www.freecodecamp.org/news/git-branching-commands-explained/

https://www.atlassian.com/git/tutorials/using-branches/git-merge . Section "Fast forward merge" is relevant for me when working as single developer not modifying main branch till development branch work is finished.

To merge newfeat into main and push to remote:
git checkout main
git merge newfeat
git push

To delete newfeat (after merge):
git branch -d newfeat
git push -d origin newfeat

==========Start log of commands executed in a test project with command output ========

[Commands I executed in a new test project]
[After creating file1.txt with some text:]
PS --path-seg-snip--\test1> git init
Initialized empty Git repository in --path-seg-snip--/test1/.git/
PS --path-seg-snip--\test1> git add .
 create mode 100644 file1.txt

[After creating GitHub private repo https://github.com/ravisiyer/git-github-test1.git]
PS --path-seg-snip--\test1> git remote add origin https://github.com/ravisiyer/git-github-test1.git
PS --path-seg-snip--\test1> git branch -M main
PS --path-seg-snip--\test1> git push -u origin main
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 232 bytes | 232.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To https://github.com/ravisiyer/git-github-test1.git
 * [new branch]      main -> main
branch 'main' set up to track 'origin/main'.
* main
PS --path-seg-snip--\test1> git branch newfeat
PS --path-seg-snip--\test1> git branch
* main
  newfeat
PS --path-seg-snip--\test1> git checkout newfeat
Switched to branch 'newfeat'
* newfeat
PS --path-seg-snip--\test1> git log
Author: ravisiyer <145967375+ravisiyer@users.noreply.github.com>
Date:   Fri May 31 22:04:31 2024 +0530
    first commit
[After modifying file1.txt]
PS --path-seg-snip--\test1> git status
Changes not staged for commit:
  (use "git restore <file>..." to discard changes in working directory)
        modified:   file1.txt
no changes added to commit (use "git add" and/or "git commit -a")
PS --path-seg-snip--\test1> git add .
PS --path-seg-snip--\test1> git commit -m "added new feature"
[newfeat d851701] added new feature
 1 file changed, 2 insertions(+), 1 deletion(-)
PS --path-seg-snip--\test1> git branch
  main
* newfeat

PS --path-seg-snip--\test1> git branch
  main
* newfeat

PS --path-seg-snip--\test1> git remote
origin

[Tried git push only to confirm that it fails.]
PS --path-seg-snip--\test1> git push
fatal: The current branch newfeat has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin newfeat

To have this happen automatically for branches without a tracking
upstream, see 'push.autoSetupRemote' in 'git help config'.

PS --path-seg-snip--\test1>
PS --path-seg-snip--\test1> git push origin newfeat
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Writing objects: 100% (3/3), 300 bytes | 75.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
remote: 
remote: Create a pull request for 'newfeat' on GitHub by visiting:
remote:      https://github.com/ravisiyer/git-github-test1/pull/new/newfeat
remote:
To https://github.com/ravisiyer/git-github-test1.git
 * [new branch]      newfeat -> newfeat
PS --path-seg-snip--\test1>
[Checked on Github and saw that now there were two branches on it: main and newfeat with file1.txt contents changing content if branch is changed using GitHub UI. Github Branches UI lists main under "Default", lists newfeat under 'Your branches' and lists newfeat under 'Active branches']

[Made further changes on local PC newfeat branch like addition of a file. Then ...]
PS --path-seg-snip--\test1> git checkout main
Switched to branch 'main'
PS --path-seg-snip--\test1> git branch
* main
  newfeat
PS --path-seg-snip--\test1> git merge newfeat
Updating ce3b24b..3efb11f
Fast-forward
 file1.txt | 3 ++-
 file2.txt | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)
 create mode 100644 file2.txt
PS --path-seg-snip--\test1> git status
On branch main
Your branch is ahead of 'origin/main' by 2 commits.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean
PS --path-seg-snip--\test1> git push
Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
To https://github.com/ravisiyer/git-github-test1.git
   ce3b24b..3efb11f  main -> main
PS --path-seg-snip--\test1>
[Now Github main shows 3 commits and is in sync with newfeat]

PS --path-seg-snip--\test1> git branch           
* main
  newfeat
PS --path-seg-snip--\test1> git branch -d newfeat
Deleted branch newfeat (was 3efb11f).
PS --path-seg-snip--\test1> git branch
* main
PS --path-seg-snip--\test1> 
[Local newfeat branch is deleted but Github still has newfeat branch]

PS --path-seg-snip--\test1> git status
On branch main
Your branch is up to date with 'origin/main'.

nothing to commit, working tree clean        
PS --path-seg-snip--\test1> git push -d origin newfeat
To https://github.com/ravisiyer/git-github-test1.git
 - [deleted]         newfeat
PS --path-seg-snip--\test1> 
[Now newfeat branch is deleted from Github too.]

==========End log of commands executed in a test project with command output ========

I followed newfeat branch creation procedure of above test case, in my gitaapp project. It already had some unstaged changes in main branch (only branch at that time), mostly related to addition of Go to Chapter Verse component.

==========Start log of commands executed in my gitaapp project with command output ========

PS --path-seg-snip--\gitaapp\dev> git status
On branch main

Changes not staged for commit:
  (use "git restore <file>..." to discard changes in working directory)
        modified:   README.md
        modified:   app/chaptersummaries.jsx
        modified:   app/ui/navbar.jsx
        modified:   package-lock.json
        modified:   package.json

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        app/ui/selectchapver.jsx

no changes added to commit (use "git add" and/or "git commit -a")
[Above output shows the files and changes made in working directory/file system but which had not been staged nor committed.]

PS --path-seg-snip--\gitaapp\dev> git branch gotochapver
PS --path-seg-snip--\gitaapp\dev> git branch
* main
[I think gotochapver was also shown initially but later when I copy-pasted whole history of commands into this file (and later to this post), it was not shown.]

PS --path-seg-snip--\gitaapp\dev> git checkout gotochapver
Switched to branch 'gotochapver'
M       app/chaptersummaries.jsx
M       app/constants.js
M       package-lock.json
M       package.json
* gotochapver
  main
[The modified files are also switched to the checkout branch. Some files don't seem to be listed above but I think here too the history of commands and their output is not accurate.]

PS --path-seg-snip--\gitaapp\dev> git add .
warning: in the working copy of 'README.md', LF will be replaced by CRLF the next time Git touches it
warning: in the working copy of 'package.json', LF will be replaced by CRLF the next time Git touches it
On branch gotochapver
Changes to be committed:
        modified:   README.md
        modified:   app/chaptersummaries.jsx
        modified:   app/constants.js
        modified:   app/ui/navbar.jsx
        new file:   app/ui/selectchapver.jsx
        modified:   package-lock.json
        modified:   package.json

PS --path-seg-snip--\gitaapp\dev> git commit -m "initial go to chapter verse impl"     
[gotochapver 0c0c7ac] initial go to chapter verse impl
 7 files changed, 183 insertions(+), 4 deletions(-)
 create mode 100644 app/ui/selectchapver.jsx
[The changes have been committed to a new commit point in gotochapver branch. main branch is unchanged.]

PS --path-seg-snip--\gitaapp\dev> git status
On branch gotochapver
nothing to commit, working tree clean
PS --path-seg-snip--\gitaapp\dev> git checkout main
Switched to branch 'main'
Your branch is up to date with 'origin/main'.
PS --path-seg-snip--\gitaapp\dev> git status
On branch main
Your branch is up to date with 'origin/main'.

nothing to commit, working tree clean
PS --path-seg-snip--\gitaapp\dev> git checkout gotochapver
Switched to branch 'gotochapver'
PS --path-seg-snip--\gitaapp\dev> git branch
* gotochapver
  main
PS --path-seg-snip--\gitaapp\dev> git push origin gotochapver
Enumerating objects: 20, done.
Counting objects: 100% (20/20), done.
Delta compression using up to 4 threads
Compressing objects: 100% (11/11), done.
Writing objects: 100% (11/11), 2.88 KiB | 41.00 KiB/s, done.
Total 11 (delta 7), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (7/7), completed with 7 local objects.
remote:
remote: Create a pull request for 'gotochapver' on GitHub by visiting:
remote:      https://github.com/ravisiyer/verysimplegita/pull/new/gotochapver
remote:
To https://github.com/ravisiyer/verysimplegita.git
 * [new branch]      gotochapver -> gotochapver
[gotochapver branch got created in Github and contents of local git gotochapver branch were pushed to it. main branch on Github is unchanged. Github branches shows gotochapver branch being 1 commit ahead of main. This is all as expected.]

PS --path-seg-snip--\gitaapp\dev>

==========End log of commands executed in my gitaapp project with command output ========

...
...
Section, "Viewing an old revision" covers usage of "git checkout" to go back to a previous commit stage.
Section, "How to undo a commit with git checkout" covers usage of "git checkout" along with "git checkout -b branch-name" to create a branch where some commit(s) are not present. However, as per my understanding, that does not remove the commit from the original branch on which the first git checkout was done.
Section, "How to undo a public commit with git revert", covers 'git revert HEAD' which "will create a new commit with the inverse of the last commit. This adds a new commit to the current branch history"... This is quite interesting. It works with public shared repositories!
Section, "How to undo a commit with git reset", covers "git reset --hard commit-point" which removes commits made after commit-point. But, as per my understanding, this works only with local repos and using it with public shared repos results in git error.
...

Comments