piątek, 24 sierpnia 2018

Git: gałęzie (branch), także zdalne

Jednym z powodów, dla których zainstersowałem się Gitem jest możliwość synchronizacji repozytoriów pomiędzy komputermi. Drugim jest wygodna praca z rozgałęzieniami kodu (branch).
Oczywiście nic nie poszło tak szybko jak się spodziewałem, dlatego postanowiłem to opisać, żebym nie musiał tego odkrywać na nowo.

Cel ćwiczenia jest zatem następujący: W moim super-projekcie hello (patrz poprzedni wpis) na jednym komputerze utworzę gałąź kodu o nazwie my-hello gdzie utworzę moduł my_hello.{c|h}.
Gałęzie w ogóle są sensowną praktyką: Pracujesz nad jakąś funkcjonalnością - utwórz sobie gałąź. A jak uznasz, że jest ok, utwórz Pull-request, żeby inni mogli przejrzeć Twoje zmiany i je ewentualnie zatwierdzić.
Ale zanim zrobię pull-request, postaram się przesiąść na inny komputer, czyli będę musiał wypchnąc gałąź my-hello, a potem ją zsynchronizować na drugim komputerze.

Zaczynam od maszyny, gdzie klonuję mój projekt, co założy mi lokalne repozytorium w katalogu hello:

$ git clone https://github.com/stecenator/hello.git
Cloning into 'hello'...
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 5 (delta 0), reused 5 (delta 0), pack-reused 0
Unpacking objects: 100% (5/5), done.
$ cd hello/

$ ls -la
razem 32
drwxrwxr-x.  3 marcinek marcinek 4096 08-24 14:38 .
drwxrwxr-x. 13 marcinek marcinek 4096 08-24 14:38 ..
drwxrwxr-x.  8 marcinek marcinek 4096 08-24 14:38 .git
-rwxrwxr-x.  1 marcinek marcinek 8264 08-24 14:38 hello
-rw-rw-r--.  1 marcinek marcinek   73 08-24 14:38 hello.c
-rw-rw-r--.  1 marcinek marcinek    8 08-24 14:38 README.md
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.

nothing to commit, working tree clean


Tworzę gałąź my-hello i modyfikuję kod:

$ git checkout -b my-hello
Switched to a new branch 'my-hello'
$ git status
On branch my-hello
nothing to commit, working tree clean

$ vim my_hello.h
$ vim my_hello.c
$ vim hello.c

$ git status
On branch my-hello
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   hello
    modified:   hello.c

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

    my_hello.c
    my_hello.h

no changes added to commit (use "git add" and/or "git commit -a")
$ git add *.c *.h
$ git status
On branch my-hello
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    modified:   hello.c
    new file:   my_hello.c
    new file:   my_hello.h

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   hello


Na koniec pracy nad modułem commit i wypycham gałąź do githuba:

$ git commit -m "Dodanie modułu my_hello"
[my-hello 6b05f85] Dodanie modułu my_hello
 3 files changed, 12 insertions(+), 2 deletions(-)
 create mode 100644 my_hello.c
 create mode 100644 my_hello.h
 

$ git push -u origin my-hello
Username for 'https://github.com': stecenator
Password for 'https://stecenator@github.com':
Total 0 (delta 0), reused 0 (delta 0)
To https://github.com/stecenator/hello.git
 * [new branch]      my-hello -> my-hello
Branch my-hello set up to track remote branch my-hello from origin.


A teraz idę do domu, odpalam drugą kompućkę i chcę znowu popracować nad tą gałęzią kodu. W tym celu muszę sobie przypomineć jakież to mam zdalne gałęzie na githubie:

Ponieważ na tej maszyne mam już repozytorium projektu hello, muszę tylko stanąć w katalogu tegoż i odświeżyć listę gałęzi kodu z githuba:

$ git fetch origin
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 5 (delta 0), reused 5 (delta 0), pack-reused 0
Unpacking objects: 100% (5/5), done.
From https://github.com/stecenator/hello
 * [new branch]      my-hello   -> origin/my-hello

$ git status
On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean


Gałąź jest już widoczna, ale git status pokazuje, że nadal pracuję na master. Ze zdalnymi gałęziami nie da się pracować. Ale można na ich podstawie utworzyć gałąź lokalną. Nawet o innej nazwie, ale to trochę szalony pomysł, więc będę się trzymał tej samej nazwy co na serwerze:

$ git checkout -b my-hello origin/my-hello
Branch 'my-hello' set up to track remote branch 'my-hello' from 'origin'.
Switched to a new branch 'my-hello'
$ ls
hello.c  my_hello.c  my_hello.h  README.md


Jak widać, w katalogu pojawiły się pliki z gałęzi my-hello utworzonej na kompie w pracy a następnie wypchniętej do Githuba.

Warto zapamiętać, że teraz mam  tak na prawdę 5 gałęzi my-hello: dwie lokalne na komputerach, dwa lokalnie zapamiętane obrazy, read-only origin/my-hello i w końcu główną origin/my-hello na Githubie.

Podsumowując, praca z gałęzią my-hello będzie wyglądać tak:
  • git fetch  - żeby zakutalizować repozytorium i lokalną kopię origin/my-hello.
  • git pull lub git checkout -b my-hello origin/my-hello  - utworzenie lokalnej gałęzi my-hello. git pull robimy, jeśli siedzimy już na gałęzi które jest Set to track remote branch, co się dzieje automatycznie jeśli choć raz zrobimy got checkout ze zdalnej :-D
  • chrum-chrum - czyli praca na kodzie z tej gałęzi.
  • git add - Wrzuca pliki do poczekalni commitu.
  • git commit - zapisuje zmiany w lokalnej gałęzi my-hello.
  • git push - aktualizuje lokalną i zdalną kopię origin/my-hello

wtorek, 21 sierpnia 2018

Git + Github jak krowie na miedzy czyli jak zacząć

Poziom bałaganu w wersjach, podwersjach, kopiach, smakach itd moich różnych skryptów w końu mnie przerósł i uznałem, że dojrzałem do używania gita i githuba. I oto co po 2 godzinach rozkminy udało mi się wykombinować na ich temat. Oczywiście trzeba się zarejestrować na github.com.
Zaczynam od utworzenia repozytorium na githubie, które reprezentuje mój projekt. Ja swój nazwałem hello
System zapoponował mi co mam z nim dalej zrobić:



Jako miłośnik command-line wybrałem bramkę nr 2 (można też nr 3, jesłi ktoś ma lokalne repozytorium gita i chce je wciśnąć w githuba) U mnie wersja nr 2 wygląda następująco:
Najpierw stworzyłem kilka plików

$ echo "# hello" >> README.md
$ git init
Initialized empty Git repository in /home/marcinek/prog/hello/.git/
$ vim hello.c
$ cat hello.c
#include <stdio.h>

int main()
{
    printf("Hello world!\n");
    return 0;
}
$ gcc -o hello hello.c
Projekt w zasadzie gotowy do zapakowania do Githuba:
 
$ git status
On branch master

No commits yet

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

    README.md
    hello
    hello.c


nothing added to commit but untracked files present (use "git add" to track)

Na czerwono git zaznaczył pliki, które pojawiły się w lokalnym katalogu/repozytorium, które nie zostały do niego dodane. Żeby git raczył je śledzić, trzeba je dodać. Jeszcze nie wiem jak zrobić, żeby pliki dodawały się automatycznie, bo jakoś nie chce mi się wierzyć, żę Linus z palca dodał każdy z kilkuset tysięcy plików kernela, ale na razie robię to ze wspomnianego palca:

$ git add *
$ git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

    new file:   README.md
    new file:   hello
    new file:   hello.c


Teraz jest już lepiej. Można zacomitować:

$ git commit -m "Pierwszy comit"
[master (root-commit) 11ac7dc] Pierwszy comit
 3 files changed, 8 insertions(+)
 create mode 100644 README.md
 create mode 100755 hello
 create mode 100644 hello.c

Ale to jeszcze nie poszło w świat. Jest teraz w gałęzi: master:

$ git status
On branch master
nothing to commit, working tree clean


No to można spróbować wypchnąć repozytorium w świat:

$ git remote add origin https://github.com/stecenator/hello.git
$ git push -u origin master
Username for 'https://github.com': stecenator    
Password for 'https://stecenator@github.com':
Counting objects: 5, done.
Delta compression using up to 12 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (5/5), 2.56 KiB | 2.56 MiB/s, done.
Total 5 (delta 0), reused 0 (delta 0)
To https://github.com/stecenator/hello.git
 * [new branch]      master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.



I gotowe!
A potem to już jest czysta zabawa:
  • Praca na wielu komputerach
  • Tworzenie rozgałęzień (branch)
  • Pull requesty (pewnie jest dużo ciekwiej, jak kilka osób pracuje nad jednym projektem)
  • Merge.
Może to kiedyś opiszę ?