Showing posts with label git. Show all posts
Showing posts with label git. Show all posts

Friday, 28 February 2025

Introduction to GitHub CLI

 


git CLI client can perform some usual tasks with the repo like creating it, cloning, commiting and pushing updates etc but some of the common actions are specific to git repository provider like GitHub or GitLab and can't be done with git client only. Such actions are creating a pull request, checking assigned issues, review requests, adding a comment to pull request etc. This article is a short intro into GitHub's CLI client, gh.

Installation


To install it on Mac:

% brew install gh 

No admin (sudo) permissions are required. 

To verify installation:

% gh
Work seamlessly with GitHub from the command line.

USAGE
  gh <command> <subcommand> [flags]

CORE COMMANDS
  auth:        Authenticate gh and git with GitHub
  browse:      Open repositories, issues, pull requests, and more in the browser
  codespace:   Connect to and manage codespaces
  gist:        Manage gists
  issue:       Manage issues
  org:         Manage organizations
  pr:          Manage pull requests
  project:     Work with GitHub Projects.
  release:     Manage releases
  repo:        Manage repositories

GITHUB ACTIONS COMMANDS
  cache:       Manage GitHub Actions caches
  run:         View details about workflow runs
  workflow:    View details about GitHub Actions workflows

ALIAS COMMANDS
  co:          Alias for "pr checkout"

ADDITIONAL COMMANDS
  alias:       Create command shortcuts
  api:         Make an authenticated GitHub API request
  attestation: Work with artifact attestations
  completion:  Generate shell completion scripts
  config:      Manage configuration for gh
  extension:   Manage gh extensions
  gpg-key:     Manage GPG keys
  label:       Manage labels
  ruleset:     View info about repo rulesets
  search:      Search for repositories, issues, and pull requests
  secret:      Manage GitHub secrets
  ssh-key:     Manage SSH keys
  status:      Print information about relevant issues, pull requests, and notifications across repositories
  variable:    Manage GitHub Actions variables

HELP TOPICS
  actions:     Learn about working with GitHub Actions
  environment: Environment variables that can be used with gh
  exit-codes:  Exit codes used by gh
  formatting:  Formatting options for JSON data exported from gh
  mintty:      Information about using gh with MinTTY
  reference:   A comprehensive reference of all gh commands

FLAGS
  --help      Show help for command
  --version   Show gh version

EXAMPLES
  $ gh issue create
  $ gh repo clone cli/cli
  $ gh pr checkout 321

LEARN MORE
  Use `gh <command> <subcommand> --help` for more information about a command.
  Read the manual at https://cli.github.com/manual
  Learn about exit codes using `gh help exit-codes`


Setting up authentication with GitHub


In GitHub website, to to Settings >> Developer Settings >> Personal access tokens and create a token with desired permissions. Copy its value and add the following environment variable to your personal settings of the terminal you use:

export GH_TOKEN=<github_personal_access_token_value>

% vi ~/.zshrc
% source ~/.zshrc

% vi ~/.bash_profile
% source ~/.bash_profile

To verify it, execute this in each terminal:

% echo $GH_TOKEN 

The output should be <github_personal_access_token_value>.


Checking the status across multiple repositories 

To check the status of the GitHub account repositories

% gh status
Assigned Issues
...
Assigned Pull Requests
...
Review Requests
...
Mentions
...
Repository Activity
...


Working with Pull Requests

Here are some common commands used to manage pull requests but make sure you are in the directory which is a GitHub repository otherwise gh will emit the error like:

failed to run git: fatal: not a git repository (or any of the parent directories): .git


To view all pull requests in a repository:

% gh pr list

It lists all open pull requests in the current repository. Use --state closed or --state all to see merged/closed PRs.

To view a specific pull request:

% gh pr view <PR_NUMBER>

or

% gh pr view <PR_URL>

It displays details of a specific PR, including description, status, and mergeability.

To open a pull request in the browser:

% gh pr view <PR_NUMBER> --web

It opens the PR page in your default web browser.

To show PRs created by you:

% gh pr list --author @me

To show PRs assigned to you:

% gh pr list --assignee @me


Working with GitHub Workflows


The main command for working with workflows is - workflow. Let's see the list of its subcommands:


% gh workflow                               
List, view, and run workflows in GitHub Actions.

USAGE
  gh workflow <command> [flags]

AVAILABLE COMMANDS
  disable:     Disable a workflow
  enable:      Enable a workflow
  list:        List workflows
  run:         Run a workflow by creating a workflow_dispatch event
  view:        View the summary of a workflow

FLAGS
  -R, --repo [HOST/]OWNER/REPO   Select another repository using the [HOST/]OWNER/REPO format

INHERITED FLAGS
  --help   Show help for command


To show all workflows and their IDs in the current repository:

gh workflow list

NAME                      STATE   ID       
my-workflow               active  131118881
...

To see the details of some workflow:

% gh workflow view my-workflow
my-workflow - my-workflow.yaml
ID: 131118881

Total runs 2
Recent runs
   TITLE        WORKFLOW     BRANCH                    EVENT              ID         
✓  my-workflow  my-workflow  project/app-upgrade/test  workflow_dispatch  13543363356
X  my-workflow  my-workflow  project/app-upgrade/test  workflow_dispatch  13158297800

To see more runs for this workflow, try: gh run list --workflow my-workflow.yaml
To see the YAML for this workflow, try: gh workflow view my-workflow.yaml --yaml

To run a workflow by creating a workflow_dispatch event:

% gh workflow run <workflow.yml> --ref <branch_name>

After triggering the workflow, you can check the status with:

% gh run list

Or check the logs of a specific run:

% gh run watch

If your workflow requires inputs, pass them using --json:

% gh workflow run build.yml --ref main --json '{"environment":"staging"}'

To see more details of a specific run:

% gh run view <run_id>

To cancel a running workflow:

% gh run cancel <run_id>


Working with GitHub Workflow Runs



% gh run 
List, view, and watch recent workflow runs from GitHub Actions.

USAGE
  gh run <command> [flags]

AVAILABLE COMMANDS
  cancel:      Cancel a workflow run
  delete:      Delete a workflow run
  download:    Download artifacts generated by a workflow run
  list:        List recent workflow runs
  rerun:       Rerun a run
  view:        View a summary of a workflow run
  watch:       Watch a run until it completes, showing its progress

FLAGS
  -R, --repo [HOST/]OWNER/REPO   Select another repository using the [HOST/]OWNER/REPO format

INHERITED FLAGS
  --help   Show help for command



% gh run list --help 
List recent workflow runs.

Note that providing the `workflow_name` to the `-w` flag will not fetch disabled workflows.
Also pass the `-a` flag to fetch disabled workflow runs using the `workflow_name` and the `-w` flag.

For more information about output formatting flags, see `gh help formatting`.

USAGE
  gh run list [flags]

ALIASES
  gh run ls

FLAGS
  -a, --all               Include disabled workflows
  -b, --branch string     Filter runs by branch
  -c, --commit SHA        Filter runs by the SHA of the commit
      --created date      Filter runs by the date it was created
  -e, --event event       Filter runs by which event triggered the run
  -q, --jq expression     Filter JSON output using a jq expression
      --json fields       Output JSON with the specified fields
  -L, --limit int         Maximum number of runs to fetch (default 20)
  -s, --status string     Filter runs by status: {queued|completed|in_progress|requested|waiting|pending|action_required|cancelled|failure|neutral|skipped|stale|startup_failure|success|timed_out}
  -t, --template string   Format JSON output using a Go template; see "gh help formatting"
  -u, --user string       Filter runs by user who triggered the run
  -w, --workflow string   Filter runs by workflow

INHERITED FLAGS
      --help                     Show help for command
  -R, --repo [HOST/]OWNER/REPO   Select another repository using the [HOST/]OWNER/REPO format

JSON FIELDS
  attempt, conclusion, createdAt, databaseId, displayTitle, event, headBranch,
  headSha, name, number, startedAt, status, updatedAt, url, workflowDatabaseId,
  workflowName

LEARN MORE
  Use `gh <command> <subcommand> --help` for more information about a command.
  Read the manual at https://cli.github.com/manual
  Learn about exit codes using `gh help exit-codes`

bojan@admins-MacBook-Pro.local /Users/bojan/repos/CheckpointGG/infra-elastic [project/elastic-upgrade/test]
% gh run list --json --help
Unknown JSON field: "--help"
Available fields:
  attempt
  conclusion
  createdAt
  databaseId
  displayTitle
  event
  headBranch
  headSha
  name
  number
  startedAt
  status
  updatedAt
  url
  workflowDatabaseId
  workflowName

---

Thursday, 11 April 2024

Git Interview Questions



  • What is Git?
  • Explain git clone command.
  • Explain git checkout command.
  • What is cherry picking?
    • When to use it? (explain how it's used for team collaboration, bug hotfixes, ...)
    • What is the syntax of git cherry pick command?
    • On which branch do we need to be before cherry picking?
    • How does the commit graph look like before and after cherry picking? (draw an example)
    • Explain its options:
      • -edit
      • --no-commit
    • Git Cherry Pick | Atlassian Git Tutorial
  • Explain git log command
  • What is the difference between git revert and reset commands. Which one should be used on public branches?
  • What is rebasing?
    • Difference between rebase and merge strategies
  • To Be Continued...

Monday, 8 August 2022

Git strategies for applying bug fixes

$ mkdir test
 
$ cd test
 
$ git init
Initialised empty Git repository in /home/bojan/dev/test/.git/
 
$ git status
On branch master

No commits yet

nothing to commit (create/copy files and use "git add" to track)
 
$ touch foo.txt
 
$ vi foo.txt
 
foo.txt:
 
feature A {
   A.1
   A.2
   A.3
}
 
$ git status
On branch master

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
    foo.txt

nothing added to commit but untracked files present (use "git add" to track)
 
$ git add foo.txt
 
$ git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
    new file:   foo.txt
 
$ git commit -m "Added feature A"
[master (root-commit) ae68f9e] Added feature A
 1 file changed, 5 insertions(+)
 create mode 100644 foo.txt

 
 
Let's now create a feature branch for feature B. Let's assume we add a bug in its first implementation.
 
$ git checkout -b feature/B
Switched to a new branch 'feature/B'
 
$ vi foo.txt 
 
foo.txt:
 
feature A {
   A.1
   A.2
   A.3
}

feature B {
   B.1
   B.2 - bug
   B.3
}
 
$ git status
On branch feature/B
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
    modified:   foo.txt

no changes added to commit (use "git add" and/or "git commit -a")
 
$ git add foo.txt 
 
$ cat foo.txt
feature A {
   A.1
   A.2
   A.3
}

feature B {
   B.1
   B.2 - bug
   B.3
}
 
$ git commit -m "Added feature B"
[feature/B c2f2c7d] Added feature B
 1 file changed, 6 insertions(+)
 
$ git log
commit c2f2c7d39fb93b3fb45ec9ff384e0ebd5303253d (HEAD -> feature/B)
Author: Bojan Komazec <bojan.komazec@example.com>
Date:   Mon Aug 8 21:36:48 2022 +0100

    Added feature B

commit ae68f9ea4bf55f54a8f40831df5b980dc30e5c6e (master)
Author: Bojan Komazec <bojan.komazec@example.com>
Date:   Mon Aug 8 21:34:20 2022 +0100

    Added feature A
 
 
$ git rebase master
Current branch feature/B is up to date.
 
$ git checkout master
Switched to branch 'master'
 
$ git merge feature/B
Updating ae68f9e..c2f2c7d
Fast-forward
 foo.txt | 6 ++++++
 1 file changed, 6 insertions(+)

 
Let's assume we've now realized that there's a bug in the current implementation of feature B.
 
 
$ git log
commit c2f2c7d39fb93b3fb45ec9ff384e0ebd5303253d (HEAD -> master, feature/B)
Author: Bojan Komazec <bojan.komazec@example.com>
Date:   Mon Aug 8 21:36:48 2022 +0100

    Added feature B

commit ae68f9ea4bf55f54a8f40831df5b980dc30e5c6e
Author: Bojan Komazec <bojan.komazec@example.com>
Date:   Mon Aug 8 21:34:20 2022 +0100

    Added feature A
 
 
$ git revert c2f2c7d39fb93b3fb45ec9ff384e0ebd5303253d
[master cd72121] Revert "Added feature B"
 1 file changed, 6 deletions(-)
 
$ git log
commit cd721217e154dc74cad4037135c0ea2c0b898696 (HEAD -> master)
Author: Bojan Komazec <bojan.komazec@example.com>
Date:   Mon Aug 8 21:42:57 2022 +0100

    Revert "Added feature B"
    
    This reverts commit c2f2c7d39fb93b3fb45ec9ff384e0ebd5303253d.

commit c2f2c7d39fb93b3fb45ec9ff384e0ebd5303253d (feature/B)
Author: Bojan Komazec <bojan.komazec@example.com>
Date:   Mon Aug 8 21:36:48 2022 +0100

    Added feature B

commit ae68f9ea4bf55f54a8f40831df5b980dc30e5c6e
Author: Bojan Komazec <bojan.komazec@example.com>
Date:   Mon Aug 8 21:34:20 2022 +0100

    Added feature A
 
 
We now want to fix the bug so we create a new branch, B2, by branching off feature/B:
 
$ git checkout feature/B
Switched to branch 'feature/B'
 
$ git checkout -b feature/B2
Switched to a new branch 'feature/B2'
 
$ cat foo.txt
feature A {
   A.1
   A.2
   A.3
}

feature B {
   B.1
   B.2 - bug
   B.3
}
 
 
$ vi foo.txt 

foo.txt:

feature A {
   A.1
   A.2
   A.3
}

feature B {
   B.1
   B.2 - bug fixed
   B.3
}
 
 
$ git status
On branch feature/B2
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
    modified:   foo.txt

no changes added to commit (use "git add" and/or "git commit -a")
 
$ git commit -a -m "Fixed bug in feature B"
[feature/B2 29dbed4] Fixed bug in feature B
 1 file changed, 1 insertion(+), 1 deletion(-)
 
$ git status
On branch feature/B2
nothing to commit, working tree clean
 
$ cat foo.txt
feature A {
   A.1
   A.2
   A.3
}

feature B {
   B.1
   B.2 - bug fixed
   B.3
}

Before we merge feature branch to trunk, we first want to rebase it:
 
 
$ git rebase -i master
Auto-merging foo.txt
CONFLICT (content): Merge conflict in foo.txt
error: could not apply 29dbed4... Fixed bug in feature B

Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".
Could not apply 29dbed4... Fixed bug in feature B
 
 
$ vi foo.txt 

We're taking all changes from feature branch.

$ git add foo.txt 
 
$ git rebase --continue
[detached HEAD b86cff8] Fixed bug in feature B
 1 file changed, 7 insertions(+)
Successfully rebased and updated refs/heads/feature/B2.
 
$ git log
commit b86cff82118bb6af2bf10a4adf584e924acaaed0 (HEAD -> feature/B2)
Author: Bojan Komazec <bojan.komazec@example.com>
Date:   Mon Aug 8 21:47:55 2022 +0100

    Fixed bug in feature B

commit cd721217e154dc74cad4037135c0ea2c0b898696 (master)
Author: Bojan Komazec <bojan.komazec@example.com>
Date:   Mon Aug 8 21:42:57 2022 +0100

    Revert "Added feature B"
    
    This reverts commit c2f2c7d39fb93b3fb45ec9ff384e0ebd5303253d.

commit c2f2c7d39fb93b3fb45ec9ff384e0ebd5303253d (feature/B)
Author: Bojan Komazec <bojan.komazec@example.com>
Date:   Mon Aug 8 21:36:48 2022 +0100

    Added feature B

commit ae68f9ea4bf55f54a8f40831df5b980dc30e5c6e
Author: Bojan Komazec <bojan.komazec@example.com>
Date:   Mon Aug 8 21:34:20 2022 +0100

    Added feature A
 
$ git status
On branch feature/B2
nothing to commit, working tree clean
 
 
We can now merge feature branch into master:
 
 
$ git checkout master
Switched to branch 'master'
 
$ git status
On branch master
nothing to commit, working tree clean
 
$ git log
commit cd721217e154dc74cad4037135c0ea2c0b898696 (HEAD -> master)
Author: Bojan Komazec <bojan.komazec@example.com>
Date:   Mon Aug 8 21:42:57 2022 +0100

    Revert "Added feature B"
    
    This reverts commit c2f2c7d39fb93b3fb45ec9ff384e0ebd5303253d.

commit c2f2c7d39fb93b3fb45ec9ff384e0ebd5303253d (feature/B)
Author: Bojan Komazec <bojan.komazec@example.com>
Date:   Mon Aug 8 21:36:48 2022 +0100

    Added feature B

commit ae68f9ea4bf55f54a8f40831df5b980dc30e5c6e
Author: Bojan Komazec <bojan.komazec@example.com>
Date:   Mon Aug 8 21:34:20 2022 +0100

    Added feature A
 
$ git merge feature/B2
Updating cd72121..b86cff8
Fast-forward
 foo.txt | 7 +++++++
 1 file changed, 7 insertions(+)
 
$ git status
On branch master
nothing to commit, working tree clean
 
$ cat foo.txt
feature A {
   A.1
   A.2
   A.3
}

feature B {
   B.1
   B.2 - bug fixed
   B.3
}



We assumed here that we had the original feature branch available. Alternatively, we could have created a new branch off the master, reverse the reverse commit, apply the fix and then merge it back to master.

Friday, 11 June 2021

Using Meld for a 3-way merge

meld is available on Ubuntu via standard package manager:
 
$ sudo apt-get update && $ sudo apt-get install meld




There is a conflict in file test.txt on branch feature which we want to merge to dev.

$ git checkout dev
 
$ git merge feature
Auto-merging test.txt
CONFLICT (content): Merge conflict in test.txt
Automatic merge failed; fix conflicts and then commit the result.
 
$ git config merge.tool meld
 
$ git mergetool
Merging:
test.txt

Normal merge conflict for 'test.txt':
  {local}: modified file
  {remote}: modified file
test.txt seems unchanged.
Was the merge successful [y/n]? n
merge of test.txt failed
 
$ git status
On branch dev
Your branch is up-to-date with 'origin/dev'.

You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

...
Unmerged paths:
  (use "git add <file>..." to mark resolution)
    both modified:   test.txt
...


 

Sunday, 28 August 2016

Git Tips and Tricks


Git is a (free) version control system. It allows:
  • saving code snapshots (commits)
  • working with alternative code versions (branches)
  • moving between branches and commits (checkout)
  • easily rolling back to older code snapshots or develop new features without breaking production code

Repository is a bucket which contains a code. 

GitHub is a platform for creating, storing and managing Git repositories in the cloud
  • allows multiple developers to work simultaneously on the centrally stored code base
  • keeps the code safe in case code is lost on dev machines for any reason
  • provides tools for automating code and repository management via GitHub Actions

Switching repositories

Cloning a remote repository:

$ git clone https://github.com/OpenVPN/openvpn-build.git



After cloning desired repository it is always good to run the following command and fetch/clone all its submodules:
$ git submodule update --init

Cloning a remote repository with preserving UNIX-style line endings:

$ git clone https://github.com/OpenVPN/openvpn-build.git --config core.autocrlf=false


Working with Branches



Getting a list of all local branches:

$ git branch



Deleting local branch:

$ git branch -d my_branch
Deleted branch my_branch (was 6d5921868b).



Getting a list of all remote branches:

$ git branch -r



Getting a list of all branches at some specific path (on Windows):

> git branch -r | find "origin/private/bojan"



Example output:

origin/HEAD -> origin/master
origin/master
origin/release/2.3



Deleting remote branch:

git push origin --delete my_branch



To update local list of remote branches:

$ git remote update origin --prune



To list all local and remote branches:

$ git branch -a




Checking out the remote branch (for the first time):

$ git checkout -b branch_name remote_name/branch_name


or shorter (on newer Git versions):

$ git checkout --track remote_name/branch_name



Example:

$ git checkout -b release/2.3 origin/release/2.3
Branch release/2.3 set up to track remote branch release/2.3 from origin.
Switched to a new branch 'release/2.3'



Or:

$ git fetch
...
* [new branch] ModuleA/Project2/JIRA-123 -> origin/ModuleA/Project2/JIRA-123
...

$ git checkout ModuleA/Project2/JIRA-123
Checking out files: 100% (1485/1485), done.
Branch ModuleA/Project2/JIRA-123 set up to track remote branch ModuleA/Project2/JIRA-123 from origin.
Switched to a new branch 'ModuleA/Project2/JIRA-123'


If you get the following error:

$ git checkout ModuleA/Project2/JIRA-123
error: Your local changes to the following files would be overwritten by checkout:
Module2/SomeDir/SomeFile.cpp
Please commit your changes or stash them before you switch branches.
Aborting


...you can force checking out with -f switch:

$ git checkout -f ModuleA/Project2/JIRA-123


To create new local branch:

$ git checkout -b issue-007
Switched to a new branch "issue-007"



The command above is a compact version for a group of these two subsequent git commands:

$ git branch issue-007
$ git checkout issue-007



To create a new branch based on a commit from the current branch:

$ git branch <commit_sha1>

To create a new branch based on a commit from another branch:

$ git branch branch_name <commit_sha1>

To create that branch and check it out:

$ git checkout -b branch_name <commit_sha1>


How to create and submit Git patch

Some open-source projects prefer submitting Git patch files to pull requests.

OpenVpn: https://community.openvpn.net/openvpn/wiki/DeveloperDocumentation
Linux kernel: https://www.kernel.org/doc/Documentation/SubmittingPatches

https://shkspr.mobi/blog/2014/04/submitting-trivial-linux-kernel-patches/
https://kernelnewbies.org/FirstKernelPatch
https://www.kernel.org/doc/Documentation/SubmittingPatches
https://www.kernel.org/pub/software/scm/git/docs/git-format-patch.html
https://git-scm.com/docs/git-format-patch

http://who-t.blogspot.co.uk/2009/12/on-commit-messages.html

Thursday, 13 November 2014

Pulling content from the remote repository via SourceTree

Here is the list of commands used by SourceTree when you pull branch mybranch from origin for some repository myrepo:

git -c diff.mnemonicprefix=false -c core.quotepath=false -c credential.helper=sourcetree fetch origin
From ssh://my.git.host:8999/myproj/myrepo
e855518..9f48d16 master -> origin/master


git -c diff.mnemonicprefix=false -c core.quotepath=false -c credential.helper=sourcetree pull --no-commit origin mybranch
From ssh://my.git.host:8999/myproj/myrepo
* branch mybranch -> FETCH_HEAD
Already up-to-date.


git -c diff.mnemonicprefix=false -c core.quotepath=false -c credential.helper=sourcetree submodule update --init --recursive

Completed successfully

We can see that main commands used here are:


git fetch origin
git pull --no-commit origin mybranch
submodule update --init --recursive