Git: Difference between revisions

→‎Get a build number: number of commits without merges
No edit summary
 
(22 intermediate revisions by the same user not shown)
Line 1: Line 1:
= Signing work =
{{DISPLAYTITLE:git}}
 
== Setting the initial config variables ==
Set user name and email address.  Without <code>--global</code> parameter it will save to the current project's .<code>/.git/config</code> file.<syntaxhighlight lang="bash">
$ git config --global user.name "Joe Shmoe"
$ git config --global user.email "jshmoe@domain.com"
</syntaxhighlight>
 
<code>push.autoSetupRemote</code> is the variable to prevent the following message for a repo that hasn't been directly pulled from the remote:
 
<syntaxhighlight lang="bash">
fatal: The current branch master has no upstream branch.
To push the current branch and set the remote as upstream, use
 
    git push --set-upstream origin master
 
To have this happen automatically for branches without a tracking
upstream, see 'push.autoSetupRemote' in 'git help config'.
</syntaxhighlight>
 
<syntaxhighlight lang="bash">
$ git config --global --add push.autoSetupRemote true
</syntaxhighlight>
 
== Signing work ==


Get your GPG configured, and a personal key installed.  Configure Git to use your personal key.
Get your GPG configured, and a personal key installed.  Configure Git to use your personal key.


<source lang="bash">
<syntaxhighlight lang="bash">
$ git config --global user.signingkey 0A46826A
$ git config --global user.signingkey 0A46826A
</source>
</syntaxhighlight>


== Signing commits ==
=== Signing commits ===


You can sign commits simply by adding -S once your environment is configured.
You can sign commits simply by adding -S once your environment is configured.


<source lang="bash">
<syntaxhighlight lang="bash">
$ git commit -S -m 'push a signed commit'
$ git commit -S -m 'push a signed commit'
</source>
</syntaxhighlight>


You can check and verify via <span class="package">git log</span>:
You can check and verify via <span class="package">git log</span>:


<source lang="bash">
<syntaxhighlight lang="bash">
$ git log --show-signature -1
$ git log --show-signature -1
</source>
</syntaxhighlight>


You can configure <span class="package">git log</span> to check any signatures and list them in output via <span class="package">%G?</span> format.
You can configure <span class="package">git log</span> to check any signatures and list them in output via <span class="package">%G?</span> format.


<source lang="bash">
<syntaxhighlight lang="bash">
$ git log --pretty="format:%h %G? %aN  %s"
$ git log --pretty="format:%h %G? %aN  %s"
</source>
</syntaxhighlight>


You can also reject commits that are unsigned and invalid:
You can also reject commits that are unsigned and invalid:


<source lang="bash">
<syntaxhighlight lang="bash">
$ git merge --verify-signature non-verify
$ git merge --verify-signature non-verify


$ git merge --verify-signatures signed-branch
$ git merge --verify-signatures signed-branch
</source>
</syntaxhighlight>


Sign the merge commit itself:
Sign the merge commit itself:


<source lang="bash">
<syntaxhighlight lang="bash">
$ git merge --verify-signatures -S signed-branch
$ git merge --verify-signatures -S signed-branch
</source>
</syntaxhighlight>
 
== Workflows ==
 
=== Making a pull request ===
 
1. Fork the project
 
 
2. Clone your fork
 
<syntaxhighlight lang="console">
$ git clone git@gitrepo.com:mhan/forkedproject.git
</syntaxhighlight>
 
 
3. Set up environment to keep fork updated
 
Set up upstream remote:
 
<syntaxhighlight lang="console">
$ git remote add upstream git@gitrepo.com:unmit/project.git
</syntaxhighlight>
 
 
Update your fork:
 
<syntaxhighlight lang="console">
$ git fetch upstream
$ git branch -va
$ git checkout master
$ git merge upstream/master
</syntaxhighlight>
 
 
4. Make updates of your own
 
Create a new branch before making any changes
 
<syntaxhighlight lang="console">
$ git checkout master
$ git branch newfeature
$ git checkout newfeature
</syntaxhighlight>
 
 
5. Submit a pull request
 
Rebase your development branch against upstream master branch.
 
<syntaxhighlight lang="console">
$ git fetch upstream
$ git checkout master
$ git merge upstream/master
$ git checkout newfeature
$ git rebase master
</syntaxhighlight>
 
 
Squash multiple commits into fewer commits
 
<syntaxhighlight lang="console">
$ git checkout
$ git rebase -i master
</syntaxhighlight>
 
 
Submit
 
* After pushing to the forked project, select development branch and click the pull request button.


= Commands =


== Tags ==
== Accepting and merging a pull request ==
 
== Commands ==
 
=== Add ===
 
Add only modified and deleted files:
 
<syntaxhighlight lang="console">
$ git add -u
</syntaxhighlight>
 
=== Tags ===


Signing tags:
Signing tags:


<source lang="bash">
<syntaxhighlight lang="bash">
$ git tag -s v2.17 -m 'version 2.17 signed by MH'
$ git tag -s v2.17 -m 'version 2.17 signed by MH'
$ git show v2.17
$ git show v2.17
</source>
</syntaxhighlight>


With the signer's public key in the keyring, you can verify the tag:
With the signer's public key in the keyring, you can verify the tag:


<source lang="bash">
<syntaxhighlight lang="bash">
$ git tag -v v2.17
$ git tag -v v2.17
</source>
</syntaxhighlight>


Upload a specific tag:
Upload a specific tag:


<source lang="bash">
<syntaxhighlight lang="bash">
$ git push origin v2.29.1
$ git push origin v2.29.1
</source>
</syntaxhighlight>


Upload all tags:
Upload all tags:


<source lang="bash">
<syntaxhighlight lang="bash">
$ git push origin --tags
$ git push origin --tags
</source>
</syntaxhighlight>
 
Remove a tag locally
 
<syntaxhighlight lang="bash">
$ git tag -d <tagname>
</syntaxhighlight>


== Get a build number ==
Remove a tag on the remote repo
 
<syntaxhighlight lang="bash">
$ git push --delete origin v0.1.8
</syntaxhighlight>
 
Get the latest tag in the current branch
 
<syntaxhighlight lang="console">
$ git describe --abbrev=0 --tags
</syntaxhighlight>
 
* Reference: [https://www.xspdf.com/resolution/50066178.html#:~:text=Git%20get%20latest%20tag%20on%20current%20branch&text=To%20get%20the%20latest%20annotated,%2Dmatch%20%2D%2Dabbrev%3D0. Tag-related commands]
 
=== Clone a specific branch ===
 
<syntaxhighlight lang="bash">
$ git clone --depth 1 --single-branch -b 2.0.0 https://github.com/user/reponame.git
</syntaxhighlight>
 
=== Get a build number ===


A commit count can be used as a build number for a revision (e.g. HEAD, master, a commit hash):
A commit count can be used as a build number for a revision (e.g. HEAD, master, a commit hash):


<source lang="bash">
<syntaxhighlight lang="bash">
$ git rev-list --count <revision>
$ git rev-list --count <revision>
</source>
</syntaxhighlight>


To get the commit count across all branches:
To get the commit count across all branches:


<source lang="bash">
<syntaxhighlight lang="bash">
$ git rev-list --all --count
$ git rev-list --all --count
</source>
</syntaxhighlight>


To get the number of commits without merges for develop branch:
To get the number of commits without merges for develop branch:


<source lang="bash">
<syntaxhighlight lang="bash">
$ git rev-list --no-merges --count develop
$ git rev-list --no-merges --count develop
</source>
</syntaxhighlight>


== Add a local branch that tracks a remote branch ==
=== Add a local branch that tracks a remote branch ===


<source lang="bash">
<syntaxhighlight lang="bash">
$ git branch --track greet origin/greet
$ git branch --track greet origin/greet
$ git branch -a
$ git branch -a
$ git merge origin/master
$ git merge origin/master
</source>
</syntaxhighlight>


== Pulling changes from a remote ==
=== Pulling changes from a remote ===


<source lang="bash">
<syntaxhighlight lang="bash">
$ git fetch
$ git fetch
$ git merge origin/master
$ git merge origin/master
</source>
</syntaxhighlight>


is equivalent to:
is equivalent to:


<source lang="bash">
<syntaxhighlight lang="bash">
$ git pull
$ git pull
</source>
</syntaxhighlight>


=== Cleaning up remote branch list ===
=== Cleaning up remote branch list ===
Line 115: Line 245:
This cleans up and removes any branches that are no longer on the remote
This cleans up and removes any branches that are no longer on the remote


<source lang="bash">
<syntaxhighlight lang="bash">
$ git remote prune origin
$ git remote prune origin
</source>
</syntaxhighlight>


== Rebase a branch ==
=== Rebase a branch ===


<source lang="bash">
<syntaxhighlight lang="bash">
$ git checkout cbranch
$ git checkout cbranch
Switched to branch 'cbranch'
Switched to branch 'cbranch'
Line 132: Line 262:


$
$
</source>
</syntaxhighlight>


== Start a new branch ==
=== Start a new branch ===


<source lang="console">
<syntaxhighlight lang="console">
$ git checkout -b newbranch
$ git checkout -b newbranch
Switched to a new branch 'newbranch'
Switched to a new branch 'newbranch'
</source>
</syntaxhighlight>


== Merge a branch ==
=== Merge a branch ===


<source lang="bash">
<syntaxhighlight lang="console">
$ git checkout autonotif
$ git checkout autonotif
Switched to branch 'autonotif'
Switched to branch 'autonotif'
Line 152: Line 282:
  1 file changed, 1 insertion(+)
  1 file changed, 1 insertion(+)
  create mode 100644 foobarrecords_savenew.hns
  create mode 100644 foobarrecords_savenew.hns
</source>
</syntaxhighlight>


Merges <branchname> onto autonotif branch
Merges <branchname> onto autonotif branch


== Delete a branch ==
 
=== Rename a branch ===
 
and update in the remote as well
 
<syntaxhighlight lang="console">
$ git checkout <old_name>
 
$ git branch -m <new_name>
 
$ git push origin --delete <old_name>
 
$ git push origin -u <new_name>
</syntaxhighlight>
 
=== Delete a branch ===


* Delete a local branch
* Delete a local branch


<source lang="bash">
<syntaxhighlight lang="bash">
$ git branch -d hotpatch1
$ git branch -d hotpatch1
</source>
</syntaxhighlight>


* Delete a remote branch
* Delete a remote branch


<source lang="bash">
<syntaxhighlight lang="bash">
git push origin --delete hotpatch1
git push origin --delete hotpatch1
</source>
</syntaxhighlight>


* Delete a remote branch that as no actual reference on the remote
* Delete a remote branch that as no actual reference on the remote


<source lang="bash">
<syntaxhighlight lang="bash">
git branch -r -d origin/hotpatch1
git branch -r -d origin/hotpatch1
</source>
</syntaxhighlight>


== List merged branches ==
=== List merged branches ===


List branches merged into master
List branches merged into master


<source lang="bash">
<syntaxhighlight lang="bash">
$ git branch --merged master
$ git branch --merged master
</source>
</syntaxhighlight>


List branches merged into HEAD (i.e. tip of current branch)
List branches merged into HEAD (i.e. tip of current branch)


<source lang="bash">
<syntaxhighlight lang="bash">
$ git branch --merged
$ git branch --merged
</source>
</syntaxhighlight>


List branches that have not been merged
List branches that have not been merged


<source lang="bash">
<syntaxhighlight lang="bash">
$ git branch --no-merged
$ git branch --no-merged
</source>
</syntaxhighlight>
 
== Remove a tag ==
 
<source lang="bash">
$ git tag -d <tagname>
</source>


== Undo last commit ==
=== Undo last commit ===


This undo is recorded as a part of the git log.
This undo is recorded as a part of the git log.


<source lang="bash">
<syntaxhighlight lang="bash">
$ git revert HEAD
$ git revert HEAD
</source>
</syntaxhighlight>


== Fix or amend last commit ==
=== Fix or amend last commit ===


<source lang="bash">
<syntaxhighlight lang="bash">
$ git commit --amend
$ git commit --amend
</source>
</syntaxhighlight>


== Reset the branch to a specific point in the past ==
=== Undo changes to a file ===


<source lang="bash">
<syntaxhighlight lang="bash">
$ git checkout -- filename
</syntaxhighlight>
 
=== Reset the branch to a specific point in the past ===
 
<syntaxhighlight lang="bash">
$ git reset --hard <hash>
$ git reset --hard <hash>
</source>
</syntaxhighlight>


--hard parameter also updates the working directory. Reset shouldn't be used in a group project on a remote repository because of its potential for confusion.
--hard parameter also updates the working directory. Reset shouldn't be used in a group project on a remote repository because of its potential for confusion.


== Ignore files ==
=== Reset the branch to a specific branch on a remote ===
 
<syntaxhighlight lang="bash">
$ git reset --hard origin/master
</syntaxhighlight>
 
=== Ignore files ===


;Temporary ignore changes to a file
;Temporary ignore changes to a file


<source lang="bash">
<syntaxhighlight lang="bash">
$ git update-index --assume-unchanged <filename>
$ git update-index --assume-unchanged <filename>
</source>
</syntaxhighlight>


;Back to tracking changes to the file
;Back to tracking changes to the file


<source lang="bash">
<syntaxhighlight lang="bash">
$ git update-index --no-assume-unchanged <filename>
$ git update-index --no-assume-unchanged <filename>
</source>
</syntaxhighlight>


;Get a list of folders and files that are <code>assume-unchanged</code>
;Get a list of folders and files that are <code>assume-unchanged</code>


<source lang="bash">
<syntaxhighlight lang="bash">
$ git ls-files -v | grep '^h'
$ git ls-files -v | grep '^h'
</source>
</syntaxhighlight>


== Ignore file modes ==
=== Ignore file modes ===


This is useful when working with multiple file systems.
This is useful when working with multiple file systems.


<source lang="bash">
<syntaxhighlight lang="bash">
$ git config core.filemode false
$ git config core.filemode false
</source>
</syntaxhighlight>


== Maintenance command ==
=== Maintenance command ===


Verify the connectivity and validity of the objects
Verify the connectivity and validity of the objects


<source lang="bash">
<syntaxhighlight lang="bash">
$ git fsck --unreachable
$ git fsck --unreachable
</source>
</syntaxhighlight>


Manage reflog information
Manage reflog information


<source lang="bash">
<syntaxhighlight lang="bash">
$ git reflog expire --expire=0 --all
$ git reflog expire --expire=0 --all
</source>
</syntaxhighlight>


Pack unpacked objects in a repository
Pack unpacked objects in a repository


<source lang="bash">
<syntaxhighlight lang="bash">
$ git repack -a -d -l
$ git repack -a -d -l
</source>
</syntaxhighlight>


Prune all unreachable objects from the object database
Prune all unreachable objects from the object database


<source lang="bash">
<syntaxhighlight lang="bash">
$ git prune
$ git prune
</source>
</syntaxhighlight>


Clean up unnecessary files and optimize the local repository
Clean up unnecessary files and optimize the local repository


<source lang="bash">
<syntaxhighlight lang="bash">
$ git gc --aggressive
$ git gc --aggressive
</source>
</syntaxhighlight>


= Useful git aliases =
== Useful git aliases ==


This is a snapshot of my ~/.gitconfig
This is a snapshot of my ~/.gitconfig


<source lang="ini">
<syntaxhighlight lang="ini">
[user]
[user]
         name = Michael Han
         name = Michael Han
Line 320: Line 471:
[merge]
[merge]
         defaultToUpstream = true
         defaultToUpstream = true
</source>
</syntaxhighlight>
 
== Quick Start Guide ==
 
* [[Git - Quick Start|Using Git for collaborating on text-based data files]]


= Links =
== Links ==


;http://qugstart.com/blog/ruby-and-rails/create-a-new-git-remote-repository-from-some-local-files-or-local-git-repository/
;http://qugstart.com/blog/ruby-and-rails/create-a-new-git-remote-repository-from-some-local-files-or-local-git-repository/
Line 342: Line 497:


'http://git-scm.com/book/en/Git-Branching-Basic-Branching-and-Merging
'http://git-scm.com/book/en/Git-Branching-Basic-Branching-and-Merging
=== Clients ===
* [https://sapling-scm.com/docs/introduction/getting-started/ Sapling]
**[https://engineering.fb.com/2022/11/15/open-source/sapling-source-control-scalable/ Meta engineering blog entry (2022-11)]

Latest revision as of 19:14, 22 February 2024


Setting the initial config variables

Set user name and email address. Without --global parameter it will save to the current project's ./.git/config file.

$ git config --global user.name "Joe Shmoe"
$ git config --global user.email "jshmoe@domain.com"

push.autoSetupRemote is the variable to prevent the following message for a repo that hasn't been directly pulled from the remote:

fatal: The current branch master has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin master

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

Signing work

Get your GPG configured, and a personal key installed. Configure Git to use your personal key.

$ git config --global user.signingkey 0A46826A

Signing commits

You can sign commits simply by adding -S once your environment is configured.

$ git commit -S -m 'push a signed commit'

You can check and verify via git log:

$ git log --show-signature -1

You can configure git log to check any signatures and list them in output via %G? format.

$ git log --pretty="format:%h %G? %aN  %s"

You can also reject commits that are unsigned and invalid:

$ git merge --verify-signature non-verify

$ git merge --verify-signatures signed-branch

Sign the merge commit itself:

$ git merge --verify-signatures -S signed-branch

Workflows

Making a pull request

1. Fork the project


2. Clone your fork

$ git clone git@gitrepo.com:mhan/forkedproject.git


3. Set up environment to keep fork updated

Set up upstream remote:

$ git remote add upstream git@gitrepo.com:unmit/project.git


Update your fork:

$ git fetch upstream
$ git branch -va
$ git checkout master
$ git merge upstream/master


4. Make updates of your own

Create a new branch before making any changes

$ git checkout master
$ git branch newfeature
$ git checkout newfeature


5. Submit a pull request

Rebase your development branch against upstream master branch.

$ git fetch upstream
$ git checkout master
$ git merge upstream/master
$ git checkout newfeature
$ git rebase master


Squash multiple commits into fewer commits

$ git checkout
$ git rebase -i master


Submit

  • After pushing to the forked project, select development branch and click the pull request button.


Accepting and merging a pull request

Commands

Add

Add only modified and deleted files:

$ git add -u

Tags

Signing tags:

$ git tag -s v2.17 -m 'version 2.17 signed by MH'
$ git show v2.17

With the signer's public key in the keyring, you can verify the tag:

$ git tag -v v2.17

Upload a specific tag:

$ git push origin v2.29.1

Upload all tags:

$ git push origin --tags

Remove a tag locally

$ git tag -d <tagname>

Remove a tag on the remote repo

$ git push --delete origin v0.1.8

Get the latest tag in the current branch

$ git describe --abbrev=0 --tags

Clone a specific branch

$ git clone --depth 1 --single-branch -b 2.0.0 https://github.com/user/reponame.git

Get a build number

A commit count can be used as a build number for a revision (e.g. HEAD, master, a commit hash):

$ git rev-list --count <revision>

To get the commit count across all branches:

$ git rev-list --all --count

To get the number of commits without merges for develop branch:

$ git rev-list --no-merges --count develop

Add a local branch that tracks a remote branch

$ git branch --track greet origin/greet
$ git branch -a
$ git merge origin/master

Pulling changes from a remote

$ git fetch
$ git merge origin/master

is equivalent to:

$ git pull

Cleaning up remote branch list

This cleans up and removes any branches that are no longer on the remote

$ git remote prune origin

Rebase a branch

$ git checkout cbranch
Switched to branch 'cbranch'

$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: added Greeter class
Applying: hello uses Greeter
Applying: updated Rakefile

$

Start a new branch

$ git checkout -b newbranch
Switched to a new branch 'newbranch'

Merge a branch

$ git checkout autonotif
Switched to branch 'autonotif'

$ git merge <branchname>
Merge made by the 'recursive' strategy.
 foobarrecords_savenew.hns | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 foobarrecords_savenew.hns

Merges <branchname> onto autonotif branch


Rename a branch

and update in the remote as well

$ git checkout <old_name>

$ git branch -m <new_name>

$ git push origin --delete <old_name>

$ git push origin -u <new_name>

Delete a branch

  • Delete a local branch
$ git branch -d hotpatch1
  • Delete a remote branch
git push origin --delete hotpatch1
  • Delete a remote branch that as no actual reference on the remote
git branch -r -d origin/hotpatch1

List merged branches

List branches merged into master

$ git branch --merged master

List branches merged into HEAD (i.e. tip of current branch)

$ git branch --merged

List branches that have not been merged

$ git branch --no-merged

Undo last commit

This undo is recorded as a part of the git log.

$ git revert HEAD

Fix or amend last commit

$ git commit --amend

Undo changes to a file

$ git checkout -- filename

Reset the branch to a specific point in the past

$ git reset --hard <hash>

--hard parameter also updates the working directory. Reset shouldn't be used in a group project on a remote repository because of its potential for confusion.

Reset the branch to a specific branch on a remote

$ git reset --hard origin/master

Ignore files

Temporary ignore changes to a file
$ git update-index --assume-unchanged <filename>
Back to tracking changes to the file
$ git update-index --no-assume-unchanged <filename>
Get a list of folders and files that are assume-unchanged
$ git ls-files -v | grep '^h'

Ignore file modes

This is useful when working with multiple file systems.

$ git config core.filemode false

Maintenance command

Verify the connectivity and validity of the objects

$ git fsck --unreachable

Manage reflog information

$ git reflog expire --expire=0 --all

Pack unpacked objects in a repository

$ git repack -a -d -l

Prune all unreachable objects from the object database

$ git prune

Clean up unnecessary files and optimize the local repository

$ git gc --aggressive

Useful git aliases

This is a snapshot of my ~/.gitconfig

[user]
        name = Michael Han
        email = mhan@pfg.fjfj.com
[core]
        editor = vim
        autocrlf = input
        safecrlf = true
[color]
        ui = always
[alias]
        co = checkout
        ci = commit
        st = status
        br = branch
        df = difftool
        hist = log --pretty=tformat:\"%C(yellow)%h %C(green)%ad %Creset| %s%C(red)%d %C(bold blue)[%an]\" --graph --date=short
	hist2 = log --graph --abbrev-commit --decorate --date=relative --format=tformat:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold blue)\" --graph --date=short
        histall = log --pretty=tformat:\"%C(yellow)%h %C(green)%ad %Creset| %s%C(red)%d %C(blue)[%an]\" --graph --date=short --all
        hist10 = !git log --pretty=tformat:\"%C(yellow)%h %C(green)%ad %Creset| %s%C(red)%d %C(blue)[%an]\" --graph --date=short | head -n 10
        hist10all = !git log --pretty=tformat:\"%C(yellow)%h %C(green)%ad %Creset| %s%C(red)%d %C(blue)[%an]\" --graph --date=short --all | head -n 10
        listnames = diff-tree --no-commit-id --name-status -r
        type = cat-file -t
        dump = cat-file -p
        ignore = update-index --assume-unchanged
        track = update-index --no-assume-unchanged
        ignorelist = !git ls-files -v | grep -s ^'h ' | cut -b 1-2 --complement[diff]
        tool = vimdiff
[difftool]
        prompt = false
[merge]
        defaultToUpstream = true

Quick Start Guide

Links

http://qugstart.com/blog/ruby-and-rails/create-a-new-git-remote-repository-from-some-local-files-or-local-git-repository/
http://gitimmersion.com/
http://kris.me.uk/2010/09/30/git-repository-server-gitolite.html
http://www.lucidlynx.com/how-to-install-gitweb-in-ubuntu/
http://mustalikachwala.blogspot.com/2012/07/ubuntu-1204-installing-gitolite-and.html
http://ben.kulbertis.org/2011/10/synchronizing-a-mysql-database-with-git-and-git-hooks/
http://viget.com/extend/backup-your-database-in-git
http://longair.net/blog/2009/04/16/git-fetch-and-merge/
a warning against pull

'http://git-scm.com/book/en/Git-Branching-Basic-Branching-and-Merging

Clients