How to use the Pure Git tool
The Pure Git tool is a model and UI of a git repository. It allows you to explore every aspect of a git repository through a set of interlinked objects with custom views. A set of operations supports a number of basic git operations such as commit, init, clone, fetch, merge, pull and push.
Contrary to Iceberg, Pure Git does explicitely not model Pharo code packages. The goal is to offer a one on one model of well know git concepts.
Getting started
Pure Git uses the git CLI interface the basics of which are necessary to continue. SeeUsing Libgit-CLI as an alternative to Libgit2 FFI in Iceberg
Make sure everything is OK as reported by the platform class.
currentIceGitCliPlatform <gtExample> ^ IceGitCliPlatform current
On disk repositories
The only thing needed to get started is a directory containing an on disk git repository.
exampleGt4Git <gtExample> <noTest> | systemRepository repository | systemRepository := IceRepository repositoryNamed: 'gt4git'. self assert: systemRepository notNil. repository := PureGitRepository on: systemRepository location. self assert: repository exists. ^ repository
exampleGToolkit <gtExample> <noTest> | systemRepository repository | systemRepository := IceRepository repositoryNamed: 'gtoolkit'. self assert: systemRepository notNil. repository := PureGitRepository on: systemRepository location. self assert: repository exists. ^ repository
Cloning from a remote
In most cases, you will start by cloning a git repository from a remote (location/server).
exampleIcebergGitCli <gtExample> <noTest> | workingDirectory gitUrl repository | workingDirectory := FileLocator temp resolve / 'example-clone'. workingDirectory exists ifTrue: [ workingDirectory deleteAll ]. gitUrl := PureGitUrl with: 'git@github.com:feenkcom/iceberg-git-cli.git'. self assert: gitUrl isScpUrl. self assert: gitUrl ownerName equals: 'feenkcom'. self assert: gitUrl repositoryName equals: 'iceberg-git-cli'. ^ (gitUrl cloneWithOwnerPrefixIn: workingDirectory) then: [ :result | repository := result repository. self assert: repository location equals: workingDirectory / gitUrl ownerName / gitUrl repositoryName. self assert: repository exists. self assert: repository hasHead. self assert: repository branch upstream remote url equals: gitUrl url. repository ]
Exploring git concepts
At its core, git is a content addressable key / value store where values are bytes and keys are hashes of those bytes. The main types of values are blobs, commits and trees.
exampleContentAddressableObjectStore <gtExample> <noTest> | repository id blob idChanged blobChanged | repository := self exampleSecondCommitInRepository. id := PureGitBlob hashText: self exampleFileContentsInRepository. self assert: id isString. self assert: id size equals: 40. self assert: (id allSatisfy: [ :each | '0123456789abcdef' includes: each ]). blob := repository resolveBlob: id. self assert: blob id equals: id. self assert: blob text equals: self exampleFileContentsInRepository. idChanged := PureGitBlob hashText: self exampleFileContentsChangedInRepository. blobChanged := repository resolveBlob: idChanged. self assert: blobChanged id equals: idChanged. self assert: blobChanged text equals: self exampleFileContentsChangedInRepository. self assert: id ~= idChanged. self assert: blob contents ~= blobChanged contents. self assert: (repository location / self exampleFilename) contents equals: self exampleFileContentsChanged. ^ Array with: blob with: blobChanged
A git commit is an elegant and efficient snapshot of the state of the whole repository's working tree.
exampleAnatomyOfACommit <gtExample> <noTest> | repository commit tree entry blob parent parentBlob changes | repository := self exampleSecondCommitInRepository. self assert: (repository location / self exampleFilename) contents equals: self exampleFileContentsChanged. commit := repository head. tree := commit tree. entry := tree entryNamed: self exampleFilename. blob := entry resolve. self assert: commit comment equals: self exampleSecondCommitComment. self assert: blob text equals: self exampleFileContentsChangedInRepository. self assert: blob id equals: (PureGitBlob hashText: self exampleFileContentsChangedInRepository). self assert: commit hasSingleParent. parent := commit parent. parentBlob := (parent tree entryNamed: self exampleFilename) resolve. self assert: commit id ~= parent id. self assert: blob id ~= parentBlob id. self assert: parentBlob text equals: self exampleFileContentsInRepository. changes := commit changesToParent. self assert: changes diffs size equals: 1. self assert: changes firstDiff numberOfLinesAdded equals: 1. self assert: changes firstDiff numberOfLinesRemoved equals: 0. self assert: changes firstDiff changeChunks first oldContents lines equals: self exampleFileContents lines. self assert: changes firstDiff changeChunks first newContents lines equals: self exampleFileContentsChanged lines. ^ commit