Difference between revisions of "Git notes"

From Wiki at Neela Nurseries
Jump to: navigation, search
m (^ Using Git and Subversion Together: - wiki syntax fix.)
m (Add link to Scott Chacon and Ben Straub book about git.)
 
(76 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
<center>
 
<center>
 
-- 2017-12-04 <!-- &#x0936;&#x0941;&#x0915;&#x094d;&#x0930;&#x0935;&#x093e;&#x0930; --> Monday - somvaar - &#x0938;&#x094b;&#x092e;&#x0935;&#x093e;&#x0930;--<br />
 
-- 2017-12-04 <!-- &#x0936;&#x0941;&#x0915;&#x094d;&#x0930;&#x0935;&#x093e;&#x0930; --> Monday - somvaar - &#x0938;&#x094b;&#x092e;&#x0935;&#x093e;&#x0930;--<br />
 +
<font size="6">
 
Git Notes<br />
 
Git Notes<br />
 +
</font>
 
</center>
 
</center>
 
<!-- &#x0936;&#x0941;&#x0915;&#x094d;&#x0930;&#x0935;&#x093e;&#x0930; -->
 
  
 
<!--
 
<!--
== [[#top|^]] OVERVIEWS - &#x0935;&#x093f;&#x0939;&#x0902;&#x0917;&#x093e;&#x0935;&#x0932;&#x094b;&#x0915;&#x0928; ==
+
https://www.unicode.org/charts/PDF/U0900.pdf  Unicode chart for Devanagari glyphs
 
-->
 
-->
 +
 
== [[#top|^]] OVERVIEW - &#x0905;&#x0935;&#x0932;&#x094b;&#x0915;&#x0928; ==
 
== [[#top|^]] OVERVIEW - &#x0905;&#x0935;&#x0932;&#x094b;&#x0915;&#x0928; ==
  
Following article / document collection of notes on version control software named <code>git</code>.
+
Following article / document collection of notes on version control software named <code>git</code>. To learn git is not a gentle or short learning curve.  This said, there are some key concepts worth mentioning at the beginning of a git learning journey.  Some of these concepts include:
 +
 
 +
<ul>
 +
*  https://nvie.com/posts/a-successful-git-branching-model/  git branching model and common git workflow in software development
 +
 
 +
*  [https://konrad126.medium.com/https-medium-com-zspajich-understanding-git-data-model-95eb16cc99f5 Zvonimir Spajic git internals] trio of articles
 +
 
 +
*  [https://docs.zephyrproject.org/latest/contribute/contributor_expectations.html#contributor-expectations Zephyr Contributor Expectations] good git practices highlighted in Zephyr RTOS Contributor Expectations document
 +
</ul>
 +
 
 +
There are many books written about git and its use and common workflows.  As of 2024 Q4, local author notes the following book that's available for free online and linked from https://www.git-scm.com/book/en/v2.  Written by Scott Chacon and Ben Straub, a brief history of git is provided in the chapter linked by:
 +
 
 +
<ul>
 +
*  https://www.git-scm.com/book/en/v2/Getting-Started-A-Short-History-of-Git
 +
</ul>
  
 +
More book references to be added here soon.
  
 
<!-- comment -->
 
<!-- comment -->
  
== [[#top|^]] How To Use Git ==
+
== [[#top|^]] Common Commands - &#x0938;&#x093E;&#x092E;&#x093E;&#x0928;&#x094D;&#x092F; &#x0906;&#x0926;&#x0947;&#x0936; ==
<br />
+
This section is meant to be first a collection of references to external articles which summarize and or present common, frequently used git commands.
Wanting to understand and use <code>git</code> better, here are some on-line references to <code>git</code> version control.  Noting here git reference at orga.cat, this reference well-written with lots of commands and concise explanations of each command. This reference is first in list:
 
 
 
  
 
Basic git commands:
 
Basic git commands:
Line 29: Line 43:
 
2020-05-06
 
2020-05-06
 
*  https://www.tutorialspoint.com/git/git_patch_operation.htm  Git patch commands, found by Joel Hart
 
*  https://www.tutorialspoint.com/git/git_patch_operation.htm  Git patch commands, found by Joel Hart
 
  
 
Atlassian article on Git's edit/stage/commit pattern of use <i>(Invoke `git add` to stage local file changes.)</i>:
 
Atlassian article on Git's edit/stage/commit pattern of use <i>(Invoke `git add` to stage local file changes.)</i>:
  
 
*  https://www.atlassian.com/git/tutorials/saving-changes
 
*  https://www.atlassian.com/git/tutorials/saving-changes
 
  
 
Setting up ssh key pairs for secure authentication:
 
Setting up ssh key pairs for secure authentication:
 
*  https://help.github.com/en/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent . . . generate new key and add key to [https://linux.die.net/man/1/ssh-agent ssh-agent]
 
*  https://help.github.com/en/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent . . . generate new key and add key to [https://linux.die.net/man/1/ssh-agent ssh-agent]
 
 
  
 
Why are my local changes getting lost?  Git commit-and-push-sequence not sufficient to transfer file changes to given git repository . . .
 
Why are my local changes getting lost?  Git commit-and-push-sequence not sufficient to transfer file changes to given git repository . . .
Line 46: Line 56:
 
*  [http://dont-be-afraid-to-commit.readthedocs.io/en/latest/git/commandlinegit.html git stage, commit, push on command line]
 
*  [http://dont-be-afraid-to-commit.readthedocs.io/en/latest/git/commandlinegit.html git stage, commit, push on command line]
 
*  [https://www.atlassian.com/git/tutorials/saving-changes git 'commit' akin to traditional 'save file', Subversion model versus Git model]
 
*  [https://www.atlassian.com/git/tutorials/saving-changes git 'commit' akin to traditional 'save file', Subversion model versus Git model]
 
  
 
Git references found while answering specific git task questions:
 
Git references found while answering specific git task questions:
Line 58: Line 67:
 
   $ git diff HEAD .
 
   $ git diff HEAD .
  
 +
2022-01-10
 +
Commands in `git` to rename local and remote branch:
 +
*  https://linuxize.com/post/how-to-rename-local-and-remote-git-branch/
 +
<i>ejemplo - board `anda-m`:</i>
 +
<pre>
 +
  1  2003  git checkout andam-board-bring-up
 +
  2  2004  git branch -m anda-m-board-bring-up
 +
  3  2005  git branch
 +
  4  2006  git push origin -u anda-m-board-bring-up
 +
  5  2007  git push origin --delete andam-board-bring-up
 +
  6  2008  history
 +
</pre>
  
 
Markdown and .md file formatting at Github
 
Markdown and .md file formatting at Github
  
 
*  [https://guides.github.com/features/mastering-markdown/ Mastering markdown]
 
*  [https://guides.github.com/features/mastering-markdown/ Mastering markdown]
 
+
*  https://anvilproject.org/guides/content/creating-links
  
 
Git and Working with Remote Repositories
 
Git and Working with Remote Repositories
Line 69: Line 90:
 
*  [https://git-scm.com/book/en/v2/Git-Basics-Working-with-Remotes git-scm dot com - book, English, version 2, "Working with Remotes"]
 
*  [https://git-scm.com/book/en/v2/Git-Basics-Working-with-Remotes git-scm dot com - book, English, version 2, "Working with Remotes"]
 
</ul>
 
</ul>
 
  
 
Release tag creation and naming in Git
 
Release tag creation and naming in Git
Line 75: Line 95:
 
*  https://git-scm.com/book/en/v2/Git-Basics-Tagging
 
*  https://git-scm.com/book/en/v2/Git-Basics-Tagging
  
 +
<!-- comment -->
  
 +
== [[#top|^]] Git Commit Messages ==
  
<!-- comment -->
+
Git Conventional Commits document, to aid in meaningful and searchable git commit messages.  Link to standard here:
 +
<ul>
 +
*  https://www.conventionalcommits.org/en/v1.0.0/
 +
</ul>
 +
 
 +
Git conventional commit messages have colon separated descriptors, the first of which are most standardized and narrow in count.  These descriptors include:
 +
 
 +
*  feat    . . . feature
 +
*  fix
 +
*  "BREAKING CHANGE"
 +
 
 +
Some additional identifiers for types of code work committed in git tracked projects include:
 +
 
 +
*  build
 +
*  chore
 +
*  ci      . . . Continuous Improvement
 +
*  docs
 +
*  style
 +
*  refactor
 +
*  revert  . . . when a commit reverts a previous commit
 +
*  perf    . . . ??? performance enhancement ???
 +
*  test
 +
 
 +
Other commit note descriptors permitted as per the [https://github.com/angular/angular/blob/22b96b9/CONTRIBUTING.md#-commit-message-guidelines Angular Convention].
 +
 
 +
<!-- odne komentar -->
  
 
== [[#top|^]] Git Command Examples ==
 
== [[#top|^]] Git Command Examples ==
 +
This section a collection of locally used commands, with some comment on the situations around and benefits of their use.
 +
<!-- odne komentar -->
  
 +
=== [[#top|^]] git querying commands ===
 
On the local work station, to see from which remote git repository a working copy comes:
 
On the local work station, to see from which remote git repository a working copy comes:
  
    $ git remote -v
+
  $ git remote -v
 +
 
 +
A git invocation to perform pattern matching like `grep`:
 +
 
 +
  $ git -C ../modules/hal/nxp/mcux/mcux-sdk grep -nC3 'FLASH_Init'
 +
 
 +
Within a git repository a developer may identify the full path to the repo or project root by issuing command:
 +
 
 +
  $ git rev-parse --show-toplevel
 +
 
 +
<!-- odne komentar -->
 +
 
 +
=== [[#top|^]] git log related commands ===
 +
A short form summary of commit messages with just the first line of each shown:
 +
 
 +
  $ git log --oneline
 +
 
 +
An `ncurses` like character graphic tree representation of a repository's commit history:
 +
 
 +
  $ git log --oneline --graph --all
 +
 
 +
Capture given git log to text file:
 +
 
 +
  $ git --no-pager log > log.txt
 +
 
 +
<!-- odne komentar -->
 +
 
 +
=== [[#top|^]] To search for changes ===
 +
This sub-section touches on searching with git for files that have changed, and for changes in files between two or more commmits.
 +
 
 +
Capture sets of changed files over a range of commits:
 +
 
 +
  $ for hash in COMMIT_HASH_1 COMMIT_HASH_2 COMMIT_HASH_3; do git diff-tree -r $hash; done
 +
 
 +
To find out which files have changed in a given branch, call git this way:
 +
 
 +
  $ git diff --name-only COMMIT_HASH_1 COMMIT_HASH_2
 +
 
 +
To see the changes in one file between two commits, call git with the 'diff' command and these four arguments:
 +
 
 +
  $ git diff COMMIT_HASH_1 COMMIT_HASH_2 -- RELATIVE_PATH_AND_FILENAME
 +
 
 +
<i>Note:  the double dash '--' separates commit hash args from filenames, as commit hashes may number more than two.  <font style="color:red">!!Pay attention note!!:  in this invocation to find file differences between two commits, git will not complain or warn of a pathspec which points to a non-extent file</font></i>
 +
 
 +
Compare commit dates to find most recently touched local branch among n branches (substitute `branch1 branch2 branch3` with your needed branch names):
  
 +
  $ for name in branch1 branch2 branch3; do git checkout ${name}; git log | head -n 3; done
  
  
<!-- comment -->
+
To search for most recently edited branches:
 +
 
 +
  $ git branch --sort=-committerdate
 +
 
 +
 
 +
<!-- odne komentar -->
 +
 
 +
=== [[#top|^]] small git workflows ===
 +
- To discard local commits and pull a newer commit history -
 +
 
 +
Sometimes to fetch remote repository updates and attempt to pull changes to a particular branch results in local git client detecting that local branch and remote branch have parted ways in their respective histories.  Git may complain `Not able to fast-forward, aborting`.  When this occurs, and fast-forwarding merges is enabled, and a developer knows that the local history does not need to be saved the following command sequence may be used to overcome this conflict of histories:
 +
 
 +
  $ git status                      # to see by how many commits the local branch has departed from its remote counterpart
 +
  $ git reset --HARD HEAD~n        # where 'n' is the number of commits by which the local branch is ahead of the remote corresponding branch
 +
  $ git pull origin &lt;branch&gt;
 +
 
 +
Some git client versions do not by default report by how many commits local branch and corresponding remote branch differ, e.g. Git for Windows bash client does not provide this difference information.  To invoke `git rev-list ...` provides an alternate way to  see commit history differences between local and remote branches.
 +
 
 +
*  https://stackoverflow.com/questions/10420575/see-exact-divergence-commits-between-local-and-remote-git-repo
 +
 
 +
<!-- odne komentar -->
 +
 
 +
== [[#top|^]] Git Inner Workings ==
 +
<span id="nn_git_three_places"></span>
 +
 
 +
<b>Key words:</b>  Three Places of Git : "Three Places of Git" : git tracked changes stored in three places
 +
 
 +
Good trio of articles by Zvonimir Spajic, on `git` inner workings, how git works under the hood.  These tutorials also explain some important git terminology.  Among the git details presented here Zvonimir explains that git "sees" a developer's changes in three places:  working directory, staging directory and local repository.  The staging directory contains a particular version controlled project's git index file.  Staged but not committed changes are kept in this index file.
 +
 
 +
<ul>
 +
*  https://konrad126.medium.com/https-medium-com-zspajich-understanding-git-data-model-95eb16cc99f5 . . . git data model
 +
*  https://konrad126.medium.com/understanding-git-branching-2662f5882f9 . . . git branching
 +
*  https://konrad126.medium.com/understanding-git-index-4821a0765cf . . . git index file
 +
</ul>
 +
 
 +
Atlassian's tutorial on `git reset` discusses git internals, the three places of git identified and described in Zvonimir's posts, but in slightly different ways:
 +
<ul>
 +
*  https://www.atlassian.com/git/tutorials/undoing-changes/git-reset
 +
</ul>
 +
 
 +
<!-- odne komentar -->
  
 
== [[#top|^]] Git Terminology ==
 
== [[#top|^]] Git Terminology ==
Line 94: Line 229:
  
 
   *  https://git-scm.com/docs/git-rebase
 
   *  https://git-scm.com/docs/git-rebase
 
 
  
 
<!-- comment -->
 
<!-- comment -->
Line 130: Line 263:
 
</pre>
 
</pre>
  
 +
 +
2022
 +
<ul>
 +
0526
 +
<ul>
 +
When and why to delete older git branches . . .
 +
*  https://ardalis.com/why-delete-old-git-branches/
 +
 +
<ul>
 +
<i>
 +
ardalis replied:<br />
 +
 +
[To delete git branches] won't impact git blame, since the commits are still present. Deleting a branch doesn't delete the commit history. A branch is basically just a pointer, pointing at a commit. Deleting the pointer leaves the commit intact.
 +
</i>
 +
</ul>
 +
 +
To delete git tags . . .
 +
*  https://www.manikrathee.com/how-to-delete-a-tag-in-git.html
 +
<ul>
 +
<i>
 +
To delete a remote tag:<br />
 +
 +
Delete the tag locally, like above<br />
 +
<ul>
 +
  git tag -d release/aug2002<br />
 +
 +
  git push origin :refs/tags/release/aug2002<br />
 +
</ul>
 +
</i>
 +
</ul>
 +
</ul>
 +
 +
 +
 +
0505
 +
<ul>
 +
*  https://intellipaat.com/community/3494/how-to-compare-files-from-two-different-branches-git-diff-file-between-branches
 +
</ul>
 +
</ul>
 +
 +
2021
 
Renaming local and remote branches:
 
Renaming local and remote branches:
 
<ul>
 
<ul>
Line 135: Line 309:
 
</ul>
 
</ul>
  
 +
0404
 +
*  https://stackoverflow.com/questions/6591213/how-do-i-rename-a-local-git-branch
 +
 +
<!-- comentario -->
 +
 +
== [[#top|^]] Git Merge ==
 +
<ul>
 +
*  https://git-scm.com/book/en/v2/Git-Branching-Rebasing
 +
 +
*  https://stackoverflow.com/questions/804115/when-do-you-use-git-rebase-instead-of-git-merge
 +
</ul>
 +
History re-writing git tools achieved through . . .
 +
<ul>
 +
*  https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History
 +
*  https://bohutskyi.com/mastering-git-commits-how-to-squash-and-simplify-your-history-d4b4a0f65864 Serhii Bohutskyi "How To Squash and Simplify Your History"
 +
</ul>
 +
 +
2023-07-12 git Kraken site:
 +
<ul>
 +
*  https://www.gitkraken.com/learn/git/git-rebase
 +
</ul>
 +
 +
<!-- comentario -->
 +
 +
== [[#top|^]] Git Rebase ==
 +
 +
To rebase in git has many uses.  Two of the highly helpful use cases are the (1) non-interactive git rebase invoked `git rebase &lt;branch&gt;`, and (2) interactive rebase invoked `git rebase -i HEAD~n`.  In the interactie use n is some n'th commit older than the current tip or HEAD commit.
 +
 +
TODO:  test whether it is trivial to use `HEAD~1` as an argument to `git rebase -i`.
 +
 +
 +
For (1) the non-interactive git rebase 'branch' can be any valid commit.  A valid commit may be expressed by a branch name, and may alternately be expressed by a commit hash.
  
<!-- comment -->
+
A or the primary use of non-interactive git rebase is to move a given branch from one parent commit to another parent commit.  In this use case a common motivation is to bring in new code features from another branch.  Non-interactive git rebase gives also the benefit of creating and maintaining a linear commit history.
 +
 
 +
Note:  in this conversation "non-interactive" does not mean there will be no code conflicts to resolve during a given rebasing task.  It is common for a branch code set undergoing rebasing to conflict with code from the new parent branch.  Git client prompts a user to resolve these conflicting code changes, and to `git add` the modified files or otherwise resolve the conflicts if the files should not be changed, or present in the new commit history.
 +
 
 +
 
 +
For (2) interactive git rebase, a common general motivation is to edit one or more commits in a range of commits.  This use of git rebase works well when the commits themselves have one or more of the following needs:
 +
<ul>
 +
1. commit needs to have commit message changed<br />
 +
2. commit needs to have one or more files edited, added and or deleted<br />
 +
3. commit needs to be combined with prior commit<br />
 +
</ul>
 +
In an interactive rebase the invocation can be of the form:
 +
 
 +
  $ git rebase -i HEAD~n
 +
 
 +
The HEAD~n git syntax specifies how many commits from the branch tip to rebase.  And in this use, rebasing commits means editing commits.
 +
 
 +
Once called to rebase interactively the git client presents a list of the commits with a column left of each commit's first line of the commit message.  This column can be edited to hold patterns or single letter abbreviations for actions like "edit", "squash" and similar.  If a commit needs to have a file edited, added or deleted, that particular commit in the list should have its default "pick" named action in the left hand column replaced with "edit" or "e".  If a commit needs to be combined with the prior commit, then that given commit should have its "pick" named action replaced with "squash" or "s".
 +
 
 +
Note: &nbsp;In order to squash commits there need to be at least two commits in the commit range specified by the last argument, `HEAD~n` given in the git command invocation.
 +
 
 +
As a supporting note not directly related to interactive git rebase, it can be helpful during rebasing workflows to have a second local project repository on hand.  That second repository can point to one and the same remote as the working local project repo.  It can then be pointed to a branch for comparison during interactive rebasing.  In other words, it may hold the branch being rebased, and show all that branch's commits during the rebase.
 +
 
 +
To see all the commits of a branch during rebase can help clarify when files need to be changed, added or removed.  In the branch undergoing rebase, only commits up to the latest commit being edited or otherwise changed are visible.
 +
 
 +
In other words, not everything in the branch being interactively rebased is visible during the rebasing steps.
 +
 
 +
TODO:  add note on good git strategy to split a commit to two or more commits.
 +
 
 +
 
 +
TO REVIEW: . . .
 +
 
 +
Intro to git rebase:
 +
<ul>
 +
*  https://medium.com/@slamflipstrom/a-beginners-guide-to-squashing-commits-with-git-rebase-8185cf6e62ec  Sam Lindstrom "Beginner's Guide to git rebase..."
 +
</ul>
 +
References to and notes on `git rebase` in this section, starting with a blog post about `git rebase --onto`:
 +
 
 +
<ul>
 +
*  https://womanonrails.com/git-rebase-onto
 +
</ul>
 +
 
 +
A good explanation of uses of `git rebase --onto commit1 commit2 [commit3]` by Enrico Campidoglio:
 +
<ul>
 +
*  https://stackoverflow.com/questions/29914052/how-to-git-rebase-a-branch-with-the-onto-command
 +
</ul>
 +
 
 +
<!-- git rebase --onto Stackoverflow answer by Enrico Campidoglio.  Answer noted here in case Stackoverflow site ever becomes not available:
 +
750
 +
tl;dr
 +
 
 +
The correct syntax to rebase B on top of A using git rebase --onto in your case is:
 +
 
 +
git checkout B
 +
git rebase --onto A B^
 +
 
 +
or rebase B on top of A starting from the commit that is the parent of B referenced with B^ or B~1.
 +
 
 +
If you're interested in the difference between git rebase <branch> and git rebase --onto <branch> read on.
 +
The Quick: git rebase
 +
 
 +
git rebase <branch> is going to rebase the branch you currently have checked out, referenced by HEAD, on top of the latest commit that is reachable from <branch> but not from HEAD.
 +
This is the most common case of rebasing and arguably the one that requires less planning up front.
 +
 
 +
          Before                          After
 +
    A---B---C---F---G (branch)        A---B---C---F---G (branch)
 +
            \                                        \
 +
              D---E (HEAD)                              D---E (HEAD)
 +
 
 +
In this example, F and G are commits that are reachable from branch but not from HEAD. Saying git rebase branch will take D, that is the first commit after the branching point, and rebase it (i.e. change its parent) on top of the latest commit reachable from branch but not from HEAD, that is G.
 +
The Precise: git rebase --onto with 2 arguments
 +
 
 +
git rebase --onto allows you to rebase starting from a specific commit. It grants you exact control over what is being rebased and where. This is for scenarios where you need to be precise.
 +
 
 +
For example, let's imagine that we need to rebase HEAD precisely on top of F starting from E. We're only interested in bringing F into our working branch while, at the same time, we don't want to keep D because it contains some incompatible changes.
 +
 
 +
          Before                          After
 +
    A---B---C---F---G (branch)        A---B---C---F---G (branch)
 +
            \                                    \
 +
              D---E---H---I (HEAD)                  E---H---I (HEAD)
 +
 
 +
In this case, we would say git rebase --onto F D. This means:
 +
 
 +
    Rebase the commit reachable from HEAD whose parent is D on top of F.
 +
 
 +
In other words, change the parent of E from D to F. The syntax of git rebase --onto is then git rebase --onto <newparent> <oldparent>.
 +
 
 +
Another scenario where this comes in handy is when you want to quickly remove some commits from the current branch without having to do an interactive rebase:
 +
 
 +
          Before                      After
 +
    A---B---C---E---F (HEAD)        A---B---F (HEAD)
 +
 
 +
In this example, in order to remove C and E from the sequence you would say git rebase --onto B E, or rebase HEAD on top of B where the old parent was E.
 +
The Surgeon: git rebase --onto with 3 arguments
 +
 
 +
git rebase --onto can go one step further in terms of precision. In fact, it allows you to rebase an arbitrary range of commits on top of another one.
 +
 
 +
Here's an example:
 +
 
 +
          Before                                    After
 +
    A---B---C---F---G (branch)                A---B---C---F---G (branch)
 +
            \                                            \
 +
              D---E---H---I (HEAD)                          E---H (HEAD)
 +
 
 +
In this case, we want to rebase the exact range E---H on top of F, ignoring where HEAD is currently pointing to. We can do that by saying git rebase --onto F D H, which means:
 +
 
 +
    Rebase the range of commits whose parent is D up to and including H on top of F.
 +
 
 +
The syntax of git rebase --onto with a range of commits then becomes git rebase --onto <newparent> <oldparent> <until>. The trick here is remembering that the commit referenced by <until> is included in the range and will become the new HEAD after the rebase is complete.
 +
Share
 +
Improve this answer
 +
Follow
 +
edited Oct 31, 2023 at 8:18
 +
answered Apr 28, 2015 at 10:05
 +
 
 +
-->
 +
 
 +
 
 +
2023 September
 +
**************
 +
 
 +
Needed to rebase a local branch to a remote branch, namely `main`, which git could not merge in its fast-forward mode.  Found solution with git invocation:
 +
 
 +
  $ git pull origin main --rebase
 +
 
 +
First created a second branch name pointing to same commit as local `main` HEAD.  Then deleted the local main branch, but not sure now whether this step is necessary.
 +
 
 +
2024 March
 +
 
 +
Ted noting that the above local branch deletion may have been a longer way to undoing local commits that are not needed.  A more straight forward way to remove local commits in order to fast forward a local branch with respect to a remote branch is:
 +
 
 +
  $ git reset --hard HEAD~n
 +
 
 +
Here n represents the number of most recent commits to prune off the local branch.  This is a destructive operation, as those local commits and their respective change sets cannot be recovered locally.  But when local commits are not needed and fast forwarding to pick up remote, shared repositories is needed, this is a good use of `git reset --hard ...`.
 +
 
 +
 
 +
Git `rerere` - Reuse Recorded Resolution
 +
 
 +
Rebasing a branch with many commits beyond its present base commit sometimes leads to repeated conflicts, as each commit in the branch history is visited.  This happens when local changes touch the same lines in the same files, between the local commits and the new base commit.  The git command `rerere` stands for Reuse Recorded Resolution.  It must be enabled with a global setting.  (From following git article sounds as though it is disabled by default)  Plus there is or are ways to use enable `rerere` per git repository, and not globally.
 +
 
 +
*  https://git-scm.com/book/en/v2/Git-Tools-Rerere  . . . author unknown
 +
 
 +
*  https://git-scm.com/docs/git-rerere
 +
 
 +
<!-- odne komentar -->
 +
 
 +
== [[#top|^]] Rebase versus Merge ==
 +
 
 +
<i>stub section</i>
 +
 
 +
<!-- odne komentar -->
 +
 
 +
== [[#top|^]] Git Diff and Related ==
 +
 
 +
Git difference command `git range-diff` available on Ubuntu like systems via package `git-extras`.  An introductory article on basic use of `range-diff` command:
 +
 
 +
*  https://www.educative.io/answers/how-to-compare-two-commit-ranges-in-git-with-git-range-diff
 +
 
 +
Git's range-diff command may also take arguments of the form:
 +
 
 +
  $ git range-diff $common_base $start_of_first_commit_series $start_hash_of_second_commit_series
 +
 
 +
<!-- odne komentar -->
 +
 
 +
== [[#top|^]] Git Tags ==
 +
 
 +
Command `git show &lt;tag_name&gt;` . . .
 +
<ul>
 +
*  https://www.freecodecamp.org/news/git-tag-explained-how-to-add-remove/
 +
</ul>
 +
 
 +
A few `git tag` command uses:
 +
<ul>
 +
<code>$ git tag</code><br />
 +
<code>$ git tag --delete &lt;tag_name&gt;</code><br />
 +
<code>$ git tag -a &lt;tag_name&gt; -m "tagging message here" [optional_commit_hash]</code><br />
 +
</ul>
 +
 
 +
<!-- comentario -->
 +
 
 +
== [[#top|^]] Git stash - stash is global across branches ==
 +
 
 +
Note that git stash "entries" are global across branches. 
 +
 
 +
*  https://www.theserverside.com/blog/Coffee-Talk-Java-News-Stories-and-Opinions/How-to-list-and-show-the-git-stash-history
 +
 
 +
Some common uses of `git stash`:
 +
 
 +
<pre>
 +
$ git stash --keep-index --include-untracked  # . . . to create a stash entry for the present branch (NEED in-page anchor to 'git index' terminology - TMH)
 +
 
 +
$ git stash list                              # . . . list stash entries for present branch
 +
 
 +
$ git stash list --all                        # . . . list stash entries for all branches of present local repository
 +
</pre>
 +
 
 +
"Use of Git stash should be the exception and not the rule." - Cameron McKenzie, Editor In Chief, TechTarget
 +
 
 +
*  https://www.theserverside.com/blog/Coffee-Talk-Java-News-Stories-and-Opinions/How-to-list-and-show-the-git-stash-history
 +
 
 +
$ git stash show
 +
 
 +
$ git stash show -p
 +
 
 +
See also details on meanings and uses of:
 +
 
 +
$ git stash pop
 +
 
 +
$ git stash apply
 +
 
 +
$ git stash drop
 +
 
 +
<!-- odne komentar -->
 +
 
 +
== [[#top|^]] Git log related ==
 +
 
 +
<i>Keywords:  git log pickaxe option</i>
 +
 
 +
A git conventions / best practices article, specific conventions for git commit messages:
 +
<ul>
 +
*  https://www.conventionalcommits.org/en/v1.0.0/#summary
 +
</ul>
 +
 
 +
Ways to invoke `git log`:
 +
 
 +
*  https://opensource.com/article/21/4/git-whatchanged  `git log --raw`, `git log --patch` and `git whatchanged`.
 +
 
 +
Git's string search parameter or "pickaxe" log option `-S`:
 +
 
 +
*  https://git-scm.com/book/en/v2/Git-Basics-Viewing-the-Commit-History
 +
 
 +
At the command line in a color supporting terminal window, the following `git` invocation produces a useful tree like representation of local and remote branches:
 +
 
 +
  $ git log --all --graph --oneline
 +
 
 +
How to limit count of commit log messages shown via `git log -{n}`, and other options:
 +
 
 +
*  https://www.atlassian.com/git/tutorials/git-log
 +
 
 +
To prune deleted remote branches from local git log:
 +
 
 +
  $ git remote prune origin
 +
 
 +
<!-- comentario -->
  
 
== [[#top|^]] Git remotes ==
 
== [[#top|^]] Git remotes ==
Working with multiple git remotes , remote repositories:
+
Working with multiple git remotes , remote repositories.  The following tutorial link to Jigarius leads to a good article.  In attempting to set up a local git remote 'definition' with two remote URLs, it became clear that there are issues that break this effort when one remote repo is already created and has pre-existing history.  It doesn't matter how short or simple that history is.  So this is a good link, but may not be practical to set up multiple remotes to be updated with a single 'push' command when the remotes are not all fully under a given developer's control:
 +
 
 
*  https://jigarius.com/blog/multiple-git-remote-repositories
 
*  https://jigarius.com/blog/multiple-git-remote-repositories
 +
 +
So another question which this prompts, this being the effort to push local work to multiple remotes, is:  how does git handle symbolic links?  Links at least in the Unix and Linux context?
 +
 +
On git handling of symlinks:
 +
 +
*  http://tdongsi.github.io/blog/2016/02/20/symlinks-in-git/
 +
 +
Adding ssh keys to ssh-agent, listing ssh keys, configuring multiple github emails:
 +
*  https://stackoverflow.com/questions/2419566/best-way-to-use-multiple-ssh-private-keys-on-one-client
 +
 +
*  https://www.kevinkuszyk.com/2018/12/10/git-tips-6-using-git-with-multiple-email-addresses/
 +
 +
How to list git configuration:
 +
 +
  $ git config --list
 +
 +
How to modify remote repository URL:
 +
 +
  $ git remote set-url origin git@github.com:[github_account_username]/[repository_name]
 +
 +
. . . this information thanks to post at https://stackoverflow.com/questions/2432764/how-do-i-change-the-uri-url-for-a-remote-git-repository.
  
 
<!-- comment -->
 
<!-- comment -->
Line 156: Line 627:
 
Looks like with latest (as of 2021-06-16) Git For Windows offers three different ways to configure credentials management.  This seems important, here is a link provided by the Git-for-Windows installer:
 
Looks like with latest (as of 2021-06-16) Git For Windows offers three different ways to configure credentials management.  This seems important, here is a link provided by the Git-for-Windows installer:
 
*  https://github.com/microsoft/Git-Credential-Manager-Core/blob/main/docs/faq.md#about-the-project
 
*  https://github.com/microsoft/Git-Credential-Manager-Core/blob/main/docs/faq.md#about-the-project
 +
Locally installed release notes at:
 +
file:///C:/Users/<user_name>/AppData/Local/Programs/Git/ReleaseNotes.html
  
 
<!-- comment -->
 
<!-- comment -->
  
 
== [[#top|^]] References ==
 
== [[#top|^]] References ==
 +
 +
Git fetch and merge preferrable to git pull . . .
 +
*  https://longair.net/blog/2009/04/16/git-fetch-and-merge/
  
 
*  https://github.com/joshnh/Git-Commands
 
*  https://github.com/joshnh/Git-Commands
  
 +
Note:  in Firefox 89.0.1 (64-bit) the key binding &lt;CTRL&gt;+j opens a message box showing download progress and history.
  
 
<!-- comment -->
 
<!-- comment -->

Latest revision as of 16:29, 4 September 2024

-- 2017-12-04 Monday - somvaar - सोमवार--
Git Notes


^ OVERVIEW - अवलोकन

Following article / document collection of notes on version control software named git. To learn git is not a gentle or short learning curve. This said, there are some key concepts worth mentioning at the beginning of a git learning journey. Some of these concepts include:

There are many books written about git and its use and common workflows. As of 2024 Q4, local author notes the following book that's available for free online and linked from https://www.git-scm.com/book/en/v2. Written by Scott Chacon and Ben Straub, a brief history of git is provided in the chapter linked by:

More book references to be added here soon.


^ Common Commands - सामान्य आदेश

This section is meant to be first a collection of references to external articles which summarize and or present common, frequently used git commands.

Basic git commands:

2020-05-06

Atlassian article on Git's edit/stage/commit pattern of use (Invoke `git add` to stage local file changes.):

Setting up ssh key pairs for secure authentication:

Why are my local changes getting lost? Git commit-and-push-sequence not sufficient to transfer file changes to given git repository . . .

Git references found while answering specific git task questions:

  $ git diff HEAD .

2022-01-10 Commands in `git` to rename local and remote branch:

ejemplo - board `anda-m`:

  1  2003  git checkout andam-board-bring-up
  2  2004  git branch -m anda-m-board-bring-up
  3  2005  git branch
  4  2006  git push origin -u anda-m-board-bring-up
  5  2007  git push origin --delete andam-board-bring-up
  6  2008  history

Markdown and .md file formatting at Github

Git and Working with Remote Repositories

Release tag creation and naming in Git


^ Git Commit Messages

Git Conventional Commits document, to aid in meaningful and searchable git commit messages. Link to standard here:

Git conventional commit messages have colon separated descriptors, the first of which are most standardized and narrow in count. These descriptors include:

  • feat . . . feature
  • fix
  • "BREAKING CHANGE"

Some additional identifiers for types of code work committed in git tracked projects include:

  • build
  • chore
  • ci . . . Continuous Improvement
  • docs
  • style
  • refactor
  • revert . . . when a commit reverts a previous commit
  • perf . . . ??? performance enhancement ???
  • test

Other commit note descriptors permitted as per the Angular Convention.


^ Git Command Examples

This section a collection of locally used commands, with some comment on the situations around and benefits of their use.

^ git querying commands

On the local work station, to see from which remote git repository a working copy comes:

 $ git remote -v

A git invocation to perform pattern matching like `grep`:

 $ git -C ../modules/hal/nxp/mcux/mcux-sdk grep -nC3 'FLASH_Init'

Within a git repository a developer may identify the full path to the repo or project root by issuing command:

 $ git rev-parse --show-toplevel


^ git log related commands

A short form summary of commit messages with just the first line of each shown:

 $ git log --oneline

An `ncurses` like character graphic tree representation of a repository's commit history:

 $ git log --oneline --graph --all

Capture given git log to text file:

 $ git --no-pager log > log.txt


^ To search for changes

This sub-section touches on searching with git for files that have changed, and for changes in files between two or more commmits.

Capture sets of changed files over a range of commits:

 $ for hash in COMMIT_HASH_1 COMMIT_HASH_2 COMMIT_HASH_3; do git diff-tree -r $hash; done

To find out which files have changed in a given branch, call git this way:

  $ git diff --name-only COMMIT_HASH_1 COMMIT_HASH_2

To see the changes in one file between two commits, call git with the 'diff' command and these four arguments:

  $ git diff COMMIT_HASH_1 COMMIT_HASH_2 -- RELATIVE_PATH_AND_FILENAME

Note: the double dash '--' separates commit hash args from filenames, as commit hashes may number more than two. !!Pay attention note!!: in this invocation to find file differences between two commits, git will not complain or warn of a pathspec which points to a non-extent file

Compare commit dates to find most recently touched local branch among n branches (substitute `branch1 branch2 branch3` with your needed branch names):

 $ for name in branch1 branch2 branch3; do git checkout ${name}; git log | head -n 3; done


To search for most recently edited branches:

 $ git branch --sort=-committerdate


^ small git workflows

- To discard local commits and pull a newer commit history -

Sometimes to fetch remote repository updates and attempt to pull changes to a particular branch results in local git client detecting that local branch and remote branch have parted ways in their respective histories. Git may complain `Not able to fast-forward, aborting`. When this occurs, and fast-forwarding merges is enabled, and a developer knows that the local history does not need to be saved the following command sequence may be used to overcome this conflict of histories:

  $ git status                      # to see by how many commits the local branch has departed from its remote counterpart
  $ git reset --HARD HEAD~n         # where 'n' is the number of commits by which the local branch is ahead of the remote corresponding branch
  $ git pull origin <branch>

Some git client versions do not by default report by how many commits local branch and corresponding remote branch differ, e.g. Git for Windows bash client does not provide this difference information. To invoke `git rev-list ...` provides an alternate way to see commit history differences between local and remote branches.


^ Git Inner Workings

Key words: Three Places of Git : "Three Places of Git" : git tracked changes stored in three places

Good trio of articles by Zvonimir Spajic, on `git` inner workings, how git works under the hood. These tutorials also explain some important git terminology. Among the git details presented here Zvonimir explains that git "sees" a developer's changes in three places: working directory, staging directory and local repository. The staging directory contains a particular version controlled project's git index file. Staged but not committed changes are kept in this index file.

Atlassian's tutorial on `git reset` discusses git internals, the three places of git identified and described in Zvonimir's posts, but in slightly different ways:


^ Git Terminology

What it means to 'rebase' in context of git . . .

  *  https://git-scm.com/docs/git-rebase


^ Git Branching

An official starting point for git branch use can be found at https://git-scm.com/docs/git-branch. Some articles on the large topic of best branching practices include:

When there are local changes that haven't been committed . . .

  *  https://stackoverflow.com/questions/20568971/git-pull-keeps-telling-me-to-stash-local-changes-before-pulling

Excerpt from above link:

It sounds like your local branch does not have all of the changes on origin.

Firstly, stash your changes

git stash

Then, pull in the changes from origin.

git fetch origin && git rebase origin/(branch name)

Next, add the stash back in to your working directory:

git stash pop


2022

2021 Renaming local and remote branches:

0404


^ Git Merge

History re-writing git tools achieved through . . .

2023-07-12 git Kraken site:


^ Git Rebase

To rebase in git has many uses. Two of the highly helpful use cases are the (1) non-interactive git rebase invoked `git rebase <branch>`, and (2) interactive rebase invoked `git rebase -i HEAD~n`. In the interactie use n is some n'th commit older than the current tip or HEAD commit.

TODO: test whether it is trivial to use `HEAD~1` as an argument to `git rebase -i`.


For (1) the non-interactive git rebase 'branch' can be any valid commit. A valid commit may be expressed by a branch name, and may alternately be expressed by a commit hash.

A or the primary use of non-interactive git rebase is to move a given branch from one parent commit to another parent commit. In this use case a common motivation is to bring in new code features from another branch. Non-interactive git rebase gives also the benefit of creating and maintaining a linear commit history.

Note: in this conversation "non-interactive" does not mean there will be no code conflicts to resolve during a given rebasing task. It is common for a branch code set undergoing rebasing to conflict with code from the new parent branch. Git client prompts a user to resolve these conflicting code changes, and to `git add` the modified files or otherwise resolve the conflicts if the files should not be changed, or present in the new commit history.


For (2) interactive git rebase, a common general motivation is to edit one or more commits in a range of commits. This use of git rebase works well when the commits themselves have one or more of the following needs:

    1. commit needs to have commit message changed
    2. commit needs to have one or more files edited, added and or deleted
    3. commit needs to be combined with prior commit

In an interactive rebase the invocation can be of the form:

  $ git rebase -i HEAD~n

The HEAD~n git syntax specifies how many commits from the branch tip to rebase. And in this use, rebasing commits means editing commits.

Once called to rebase interactively the git client presents a list of the commits with a column left of each commit's first line of the commit message. This column can be edited to hold patterns or single letter abbreviations for actions like "edit", "squash" and similar. If a commit needs to have a file edited, added or deleted, that particular commit in the list should have its default "pick" named action in the left hand column replaced with "edit" or "e". If a commit needs to be combined with the prior commit, then that given commit should have its "pick" named action replaced with "squash" or "s".

Note:  In order to squash commits there need to be at least two commits in the commit range specified by the last argument, `HEAD~n` given in the git command invocation.

As a supporting note not directly related to interactive git rebase, it can be helpful during rebasing workflows to have a second local project repository on hand. That second repository can point to one and the same remote as the working local project repo. It can then be pointed to a branch for comparison during interactive rebasing. In other words, it may hold the branch being rebased, and show all that branch's commits during the rebase.

To see all the commits of a branch during rebase can help clarify when files need to be changed, added or removed. In the branch undergoing rebase, only commits up to the latest commit being edited or otherwise changed are visible.

In other words, not everything in the branch being interactively rebased is visible during the rebasing steps.

TODO: add note on good git strategy to split a commit to two or more commits.


TO REVIEW: . . .

Intro to git rebase:

References to and notes on `git rebase` in this section, starting with a blog post about `git rebase --onto`:

A good explanation of uses of `git rebase --onto commit1 commit2 [commit3]` by Enrico Campidoglio:


2023 September

Needed to rebase a local branch to a remote branch, namely `main`, which git could not merge in its fast-forward mode. Found solution with git invocation:

 $ git pull origin main --rebase

First created a second branch name pointing to same commit as local `main` HEAD. Then deleted the local main branch, but not sure now whether this step is necessary.

2024 March

Ted noting that the above local branch deletion may have been a longer way to undoing local commits that are not needed. A more straight forward way to remove local commits in order to fast forward a local branch with respect to a remote branch is:

  $ git reset --hard HEAD~n

Here n represents the number of most recent commits to prune off the local branch. This is a destructive operation, as those local commits and their respective change sets cannot be recovered locally. But when local commits are not needed and fast forwarding to pick up remote, shared repositories is needed, this is a good use of `git reset --hard ...`.


Git `rerere` - Reuse Recorded Resolution

Rebasing a branch with many commits beyond its present base commit sometimes leads to repeated conflicts, as each commit in the branch history is visited. This happens when local changes touch the same lines in the same files, between the local commits and the new base commit. The git command `rerere` stands for Reuse Recorded Resolution. It must be enabled with a global setting. (From following git article sounds as though it is disabled by default) Plus there is or are ways to use enable `rerere` per git repository, and not globally.


^ Rebase versus Merge

stub section


^ Git Diff and Related

Git difference command `git range-diff` available on Ubuntu like systems via package `git-extras`. An introductory article on basic use of `range-diff` command:

Git's range-diff command may also take arguments of the form:

  $ git range-diff $common_base $start_of_first_commit_series $start_hash_of_second_commit_series


^ Git Tags

Command `git show <tag_name>` . . .

A few `git tag` command uses:

    $ git tag
    $ git tag --delete <tag_name>
    $ git tag -a <tag_name> -m "tagging message here" [optional_commit_hash]


^ Git stash - stash is global across branches

Note that git stash "entries" are global across branches.

Some common uses of `git stash`:

$ git stash --keep-index --include-untracked   # . . . to create a stash entry for the present branch (NEED in-page anchor to 'git index' terminology - TMH)

$ git stash list                               # . . . list stash entries for present branch

$ git stash list --all                         # . . . list stash entries for all branches of present local repository

"Use of Git stash should be the exception and not the rule." - Cameron McKenzie, Editor In Chief, TechTarget

$ git stash show

$ git stash show -p

See also details on meanings and uses of:

$ git stash pop

$ git stash apply

$ git stash drop


^ Git log related

Keywords: git log pickaxe option

A git conventions / best practices article, specific conventions for git commit messages:

Ways to invoke `git log`:

Git's string search parameter or "pickaxe" log option `-S`:

At the command line in a color supporting terminal window, the following `git` invocation produces a useful tree like representation of local and remote branches:

  $ git log --all --graph --oneline

How to limit count of commit log messages shown via `git log -{n}`, and other options:

To prune deleted remote branches from local git log:

  $ git remote prune origin


^ Git remotes

Working with multiple git remotes , remote repositories. The following tutorial link to Jigarius leads to a good article. In attempting to set up a local git remote 'definition' with two remote URLs, it became clear that there are issues that break this effort when one remote repo is already created and has pre-existing history. It doesn't matter how short or simple that history is. So this is a good link, but may not be practical to set up multiple remotes to be updated with a single 'push' command when the remotes are not all fully under a given developer's control:

So another question which this prompts, this being the effort to push local work to multiple remotes, is: how does git handle symbolic links? Links at least in the Unix and Linux context?

On git handling of symlinks:

Adding ssh keys to ssh-agent, listing ssh keys, configuring multiple github emails:

How to list git configuration:

  $ git config --list

How to modify remote repository URL:

  $ git remote set-url origin git@github.com:[github_account_username]/[repository_name]

. . . this information thanks to post at https://stackoverflow.com/questions/2432764/how-do-i-change-the-uri-url-for-a-remote-git-repository.


^ Using Git and Subversion Together

Using Git and Subversion on one and the same project looks complicated . . .


^ Git For Windows notes

Looks like with latest (as of 2021-06-16) Git For Windows offers three different ways to configure credentials management. This seems important, here is a link provided by the Git-for-Windows installer:

Locally installed release notes at: file:///C:/Users/<user_name>/AppData/Local/Programs/Git/ReleaseNotes.html


^ References

Git fetch and merge preferrable to git pull . . .

Note: in Firefox 89.0.1 (64-bit) the key binding <CTRL>+j opens a message box showing download progress and history.