Login Login
MORE

WIDGETS

Widgets

Wanted articles
Who is online?
Article tools

CSharp:Source Control - Git operazioni tipiche

From Aino Wiki

Jump to: navigation, search

Schema di scenario tipico

Git schema flusso main 01.png

Doc:

Basi

Termini:

  • Object Database, è il database chiave/valore conservato nella cartella nascosta .git. la chiave è un valore calcolato in SHA1, il valore è il contenuto del file.
  • il file system è la directory con i files.
  • il repository è il database locale su file che conserva i vari commit
  • staging area o index, fa da tramite tra il file system ed il repository. E' uno spazio dove parcheggiare gli oggetti pronti per il prossimo commit mediante il quale finiranno nel repository.
  • il remote repository è un repository su altro computer col quale si può chiedere che lui si allinei al nostro contenuto o ci si può allinearsi al suo i comandi a disposizione per farlo sono rispettivamente: push e fetch.

Tools

Per il sistema operativo Windows:

  • Git CMD, è un prompt comandi DOS ma che è collegato a funzionalità Git quindi è usato per gestire da "Terminale" (linea comando) un repository Git mediante i comandi spiegati qui sotto.
  • Git GUI, è una Windows application quindi una GUI per lavorare con un repository Git.
  • Git Bash, simile a Git CMD ma che ricorda un terminale Linux, appunto Bash, serve a gestire archivi Git sul file system.
  • Gitk, è una Windows application quindi una GUI che serve a visualizzare\gestire i commit di Git anche quelli "nascosti". Si può lanciare da Git CMD (es. gitk o per visualizzare anche quelli nascosti gitk --all)

Tabella comandi

git help -a
usage: git [--version] [--help] [-c name=value]
           [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
           [-p|--paginate|--no-pager] [--no-replace-objects] [--bare]
           [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
           <command> [<args>]

available git commands in '/usr/local/Cellar/git/1.8.4/libexec/git-core'

  add               config                    gc                 merge-one-file   relink             show-ref
  add--interactive  count-objects             get-tar-commit-id  merge-ours       remote             stage
  am                credential                grep               merge-recursive  remote-ext         stash
  annotate          credential-cache          gui                merge-resolve    remote-fd          status
  apply             credential-cache--daemon  gui--askpass       merge-subtree    remote-ftp         stripspace
  archimport        credential-store          hash-object        merge-tree       remote-ftps        submodule
  archive           cvsexportcommit           help               mergetool        remote-http        svn
  bisect            cvsimport                 http-backend       mktag            remote-https       symbolic-ref
  bisect--helper    cvsserver                 http-fetch         mktree           remote-testsvn     tag
  blame             daemon                    http-push          mv               repack             tar-tree
  branch            describe                  imap-send          name-rev         replace            unpack-file
  bundle            diff                      index-pack         notes            repo-config        unpack-objects
  cat-file          diff-files                init               p4               request-pull       update-index
  check-attr        diff-index                init-db            pack-objects     rerere             update-ref
  check-ignore      diff-tree                 instaweb           pack-redundant   reset              update-server-info
  check-mailmap     difftool                  log                pack-refs        rev-list           upload-archive
  check-ref-format  difftool--helper          lost-found         patch-id         rev-parse          upload-pack
  checkout          fast-export               ls-files           peek-remote      revert             var
  checkout-index    fast-import               ls-remote          prune            rm                 verify-pack
  cherry            fetch                     ls-tree            prune-packed     send-email         verify-tag
  cherry-pick       fetch-pack                mailinfo           pull             send-pack          web--browse
  citool            filter-branch             mailsplit          push             sh-i18n--envsubst  whatchanged
  clean             fmt-merge-msg             merge              quiltimport      shell              write-tree
  clone             for-each-ref              merge-base         read-tree        shortlog
  column            format-patch              merge-file         rebase           show
  commit            fsck                      merge-index        receive-pack     show-branch
  commit-tree       fsck-objects              merge-octopus      reflog           show-index

Comandi consueti

Per Git versione Windows:

Comando___Git Descrizione___________________________ Es.
git init Inizializzazione del repository. Da lanciare nella cartella del progetto da gestire
  • git init Comando da dare nella cartella radice del progetto da conservare
  • git init ProgettoTest01.git
git add Ufficializza l'aggiunta dei nuovi files nell'indice dei files da gestire, i files sono aggiunti alla staging area
  • git add .
  • git add NomeFile.Estensione
  • git add -p avvia una sessione interattiva che permette di scegliere quali porzioni dei file modificati vanno aggiunte alla staging area
git commit Rende definitive le modifiche aggiunndo un commento che le gescrive e che vale per l'intero insieme di modifiche git commit -m "Prima versione del progetto"
git log Per avere l'elenco cronologico di tutti i commit
  • git log
  • git log *.cs
  • git log --oneline visualizza i commit una riga per volta con in testa il codice identificativo del commit
  • git log --graph --all --oneline visualizzerà tutti i commit anche quelli storici nascosti
git diff mostra le differenze tra l’attuale contenuto della staging area e l’ultimo commit git diff --staged
git stash serve per mettere da parte tutte le attuali modifiche non committate, per recuperarle in un secondo momento.
  • git stash
  • git stash listgit stash drop stash@{1} rimuove uno specifico stash (1)
  • git stash clear elimina tutti gli stash
git tag -a <TAG_NAME> Per marchiare un intero set di files, fotografia corrente del progetto, con un codice di versione al quale riferirvisi nel complessivo, è un segnalibro. git tag v1.1.0 -m "tagging version 1.1.0"
git amend è una scorciatoia che ci permette di unire nuove modifiche presenti nella staging area all’ultimo commit appena salvato, prima va fatto l'add delle novità aggiunte.

L’opzione –no-edit che istruisce Git a mantenere l’esistente messaggio di commit.

git commit --amend --no-edit
git push Per pubblicare le modifiche sul server remoto. Ovviamente loaclmente deve esser stato affettuato l'eventuale add e commit precedente.
  • git push origin #
  • git push foobar master #Suposto che il repository remoto abbia alias "foobar"
  • git push --set-upstream foobar master #Suposto che il repository remoto abbia alias "foobar"

NOTA Per capire cosa scrivere dopo "push" aprire il file config andare alla sezione [remote "XXX"], al posto di XXX ci può essere origin o foobar

git fetch Per prelevare da Git (locale o remoto) sovrascrivendo i file locali, quindi ignorando tutte le modifiche locali
  • git fetch
  • git checkout origin/main

oppure

  • git reset --hard origin
git status Mostra lo stato attuale del repository, indicando i file modificati, eliminati o aggiunti .
git remote Per lavorare con un repository remoto quindi collegare il locale con uno specifico remoto indicando a git il suo indirizzo. NOTA si possono avere più repository remoti per uno stesso progetto locale.
  • git remote -v          Per avere la URL del progetto corrente
  • git remote add foobar http://SPXMIW3658/Git_IIS/repo-remoto Per aggiungere al repository locale il riferimento ad uno remoto
git checkout Serve per tornare indietro ad un precedente commit. Occorre però conoscere l'ID del commit e lo si fa mediante il comando git log --oneline che restituirà un elenco tabellare in cui la prima colonna indicherà il codice ID ad es. 43474fb Per rendere più comodo l'identificazione del commit voluto anche tra quelli non visibili usare gitk --all

NOTA che l'Id in realtà è un puntatore.

git checkout 43474fb
git branch Per impostare un branch. Un branch in realtà è una etichetta assegnata ad un Commit per facilitare il riferimento in eventuali checkout ovvero cambi di "contesto".

A proposito si usa un segnaposto "HEAD" che punta sempre al commit su sui ci si trova

  • git branch bob 56674fb # qui sto usando la chiave del commit per assegnare una etichetta
  • git branch -d Br_Secondo # per cancellare l'etichetta (NON il commit!)
  • git branch #Per vedere l’elenco dei branch locali disponibili
  • git branch -r #Per vedere l’elenco dei branch remoti
git clone Per prelevare il contenuto di un determinato progetto remoto.

Successivamente, per aggiornare il progetto locale (a meno di modifiche locali successive) si potrà usare git fetch senza argomenti per aggiornare quel che è localmente deve corrispondere ai remote-tracking branches e git pull senza argomenti per fare il merge con quanto è in locale.

git clone http://GitUser1@git.myserver.com/Git_IIS/ProgettoTest01.git CartellaLocale #Copia via HTTP il ProgettoTest01 dal server remoto "git.myserver.com" usando lo user "GitUser1" e lo mette nella cartella locale "CartellaLocale"
git pull Per prelevare tutte le modifiche da un progetto già collegato (per cui s'è già eseguito il CLONE). NOTA andare dentro la cartella del progetto e lanciare il comando
  • git pull
  • git pull foobar master

NOTA per capire cosa scrivere dopo "pull" aprire il file config andare alla sezione [remote "XXX"], al posto di XXX ci può essere origin o foobar

git config Per impostare informazioni di configurazione locali o globali di Git.

NOTA per poter committare qualcosa occorre impostare l'utente corrente!

  • git config --list #Per avere l'elenco di tutti parametri di configurazione nel file config, es per le info sull'utente corrente
  • git config --global user.name "Giuseppe Aino" #Per impostare l'utente globale
  • git config --global user.email xxx.yyy@gmail.it #Per impostare l'email dell'utente globale

NOTA

  • Eventuali cartelle vuote NON verranno aggiunte o committate, occorre che abbiamo almeno un file.

Esempi

Configurazione

Es Cfg locale

Segue un file di configurazione (.\.git\config ) per un repository locale:

  • che è collegato ad un repository remoto chaimato "foobar".
  • è ti tipo locale quindi "non-bare".
  • ha tre branch: "master", "experiment" e "Ultimo1".
[core]
	repositoryformatversion = 0
	filemode = false
	bare = false
	logallrefupdates = true
	ignorecase = true
[remote "foobar"]
	url = http://GitUser1@SPXMIW3658/Git_IIS/repo-remoto
	fetch = +refs/heads/*:refs/remotes/foobar/*
[branch "master"]
	remote = foobar
	merge = refs/heads/master
[branch "experiment"]
	remote = foobar
	merge = refs/heads/experiment
[branch "Ultimo1"]
	remote = foobar
	merge = refs/heads/Ultimo1

Es Cfg remoto

Un file di configurazione .\.git\config potrebbe esser così (non-bare repository):

[core]
	repositoryformatversion = 0
	filemode = false
	bare = false
	logallrefupdates = true
	ignorecase = true
[receive]
	denyCurrentBranch = ignore

Repository locale

Es definizione repository locale 1

Per iniziare con un repository da gestire col servizio Git si può partire usando i segeunti comandi:

D:\temp\testGit> md ProgettoTest01.git
D:\temp\testGit> cd ProgettoTest01.git
D:\temp\testGit\ProgettoTest01.git> git init
D:\temp\testGit\ProgettoTest01.git> git add .
D:\temp\testGit\ProgettoTest01.git> git commit -m "Contenuto di partenza"
D:\temp\testGit\ProgettoTest01.git> git log

Ora su un PC client si può già scaricare il repository di ProgettoTest01.git, ma la working directory sarà vuota.
Aggiungere un file, "PrimoFile.txt":

D:\temp\testGit\ProgettoTest01.git> git add PrimoFile.txt
D:\temp\testGit\ProgettoTest01.git> git commit -m "Primo file"
D:\temp\testGit\ProgettoTest01.git> git log

Es Commit con Add e Remove

Invece di fare un Add e poi un Commit o fare un Remove e Commit finale, c'è il seguente comando comodo:

git commit -am "Commit genrico purificato da file cancellati e aggiornato con integrazione e modifiche"

PS per rimuvare file: git rm file\_name

Es Creazione ed uso di Branch

Un branch crea una etichetta ad un commit Supponendo dia vere la seguente situazione:

Git branch 01.png

Si crea il seguente Branch chiamandolo "Br_Secondo"

git branch Br_Secondo 9c82359
Git branch 02.png

Quindi per usarlo ovvero per cambiare barnch si usa il comando checkout:

git checkout Br_Secondo

Per tornare sul set principale del progetto occorre spostarsi sul "master" (che è il principale dei branch!):

git checkout master

Per visualizzare le modifiche tra 2 branch si usa diff:

git diff Br_Secondo master

Nota "master" è banalmente un brach che c'è sempre

Interazioni remote

Es agginta riferimento remoto

Si aggiunge localmente il riferimento ad un repository remoto (che è vuoto):

Git fetch da remoto 01.png

Nel caso sia necessaria una autenticazione, si indica lo user@... :

git remote add foobar http://GitUser1@SPXMIW3658/Git_IIS/repo-remoto

Es Remote 2 (no upstream)

Nel caso di pubblicazione verso remoto e non ci siano branch dopo aver ricevuto l'errore "fatal: The current branch master has no upstream branch":

git push --set-upstream foobar master

Si suppone si sia configurato il repository remoto "foobar"

Es Remote 3 Scaricare

Il comando da usare è fetch, può esser necessario un ulteriore comando git pull

git fetch foobar
git pull

Si suppone si sia configurato il repository remoto "foobar"

Es Remote bare repository 1

Esempio di creazione di un repository centralizzato su un server e due PC client A e B.
Supponendo di essere sul server remoto XXX su cui è attiva una applicazione Web configurata su IIS associata alla cartella D:\Git_Repository\Git_IIS ( guida interna).
Si crea il "bare repository" usando Git CMD:

git init --bare repo-remoto

che produce:

Git bare repository 04.png

Ora si popolerà il repository remoto con un progetto già esistente e controllato mediante Git. Supponiamo che tale repository sia su un PC client, PC A, e nella cartella F:\Git_TestLocal\progetto.
Si associa il repository locale al repository remoto dando un nome in alias "foobar", supponiamo anche che si adotti la "basic authentication" quindi sul server XXX ci sia un utente di sistema operativo chiamato 'GitUser1'.

git remote add foobar http://GitUser1@XXX/Git_IIS/repo-remoto

Il comando precedente ha aggiornato il file ".git\config" sul PC A.
Quindi ora si può popolare il repository remoto con un camando push mediante Git CMD:

git push foobar master

con questo output di esempio:

Git bare repository push master 04.png

L'effetto sarà quello per cui la cartella "objects" si riempirà di sottocartelle prima non esistenti che si aggiungono alle due: "info" e "pack".
A questo punto si testa tutto andando su un altro PC client, il PC B, e si lancia il comando clone del repository remoto su XXX:

git clone http://GitUser1@XXX/Git_IIS/repo-remoto

che produrra' il seguente output:

Git bare repository clone 05.png

Si verificherà la creazione locale della cartella progetto con gli stessi file della cartella del primo PC.

Conflitti

Es 1 contenuto file conteso

Supponendo un server XXX con bare repository e due PC client A e B, un file "Prova.txt" ha una modifica dal PC A ed un'altra che si sovrappone a quella del PC B. (Per ora non mostro la soluzione al problema che sarà da implementare manualmente)
Sul PC A:
Il progetto si chiama 'AutoMouseOver' ed file in conflitto Prova.txt

uno
due
tre
--------------
quattro
cinque
Git conflict 01 PC A .png

Sul PC B:
File Prova.txt

uno
due
tre
--------------
XXXX
Git conflict 02 PC B.png

Problemi Soluzioni

Agg.to server remoto

Si effettua un git push su server remoto e si riceve un errore:

remote: error: refusing to update checked out branch: refs/heads/master
remote: error: By default, updating the current branch in a non-bare repository
remote: is denied, because it will make the index and work tree inconsistent
remote: with what you pushed, and will require 'git reset --hard' to match the work tree to HEAD.

remote: You can set the 'receive.denyCurrentBranch' configuration variable
remote: to 'ignore' or 'warn' in the remote repository to allow pushing into
remote: its current branch; however, this is not recommended unless you
remote: arranged to update its work tree to match what you pushed in some
remote: other way.

Una soluzione è lanciare il seguente comando sul server:

git config receive.denyCurrentBranch ignore
----oppure:
git config receive.denyCurrentBranch warn

Il file di configurazione .\.git\config potrebbe esser così (non-bare repository):

[core]
	repositoryformatversion = 0
	filemode = false
	bare = false
	logallrefupdates = true
	ignorecase = true
[receive]
	denyCurrentBranch = ignore

Sul server sono recepite le modifiche ma non si vedranno i nuovi files a meno da non resettare tutto che riporterà, come voluto, alla versione sul client remoto. Sul server eseguire:

git reset --hard

Dopo questo il push funzionerà.
Fonti:

Traformare un repository da non-bare a bare

In short: replace the contents of repo with the contents of repo/.git, then tell the repository that it is now a bare repository.

To do this, execute the following commands:

cd repo
mv .git ../repo.git # renaming just for clarity
cd ..
rm -fr repo
cd repo.git
git config --bool core.bare true

Note that this is different from doing a git clone --bare /path/to/repo to a new location (as described qui).

Consider this scenario Your origin had 100 branches You have only checked out 10 of them locally Your bare repo will only have the 10 You send the bare repo somewhere It would be missing 90 repos If that's your intention, that's fine. If you needed a mirror of the remote/origin, this is not the way.

Mappa e Link


C# | Source Control | Git | Git in Visual Studio


Visual Studio | MS SQL | Dizionario


Parole chiave:

Author