62d02a2b32a70ea162ebb17407bd1de47a8e8906
[jelmer/dulwich.git] / docs / tutorial / 1-initial-commit.txt
1 The Repository
2 ==============
3
4 After this introduction, let's start directly with code::
5
6   >>> from dulwich.repo import Repo
7
8 The access to every object is through the Repo object. You can open an
9 existing repository or you can create a new one. There are two types of Git
10 repositories:
11
12   Regular Repositories -- They are the ones you create using ``git init`` and
13   you daily use. They contain a ``.git`` folder.
14
15   Bare Repositories -- There is not ".git" folder. The top-level folder
16   contains itself the "branches", "hooks"... folders. These are used for
17   published repositories (mirrors).
18
19 Let's create a folder and turn it into a repository, like ``git init`` would::
20
21   >>> from os import mkdir
22   >>> mkdir("myrepo")
23   >>> repo = Repo.init("myrepo")
24   >>> repo
25   <Repo at '/tmp/myrepo/'>
26
27 You can already look a the structure of the "myrepo/.git" folder, though it
28 is mostly empty for now.
29
30 Initial commit
31 ==============
32
33 When you use Git, you generally add or modify content. As our repository is
34 empty for now, we'll start by adding a new file::
35
36   >>> from dulwich.objects import Blob
37   >>> blob = Blob.from_string("My file content")
38   >>> blob.id
39   '456a1e689eb87b947be24562e830421cd799388c'
40
41 Of course you could create a blob from an existing file using ``from_file``
42 instead.
43
44 As said in the introduction, file content is separed from file name. Let's
45 give this content a name::
46
47   >>> from dulwich.objects import Tree
48   >>> tree = Tree()
49   >>> tree.add(0100644, "spam", blob.id)
50
51 Note that "0100644" is the octal form for a regular file with common
52 permissions. You can hardcode them or you can use the ``stat`` module.
53
54 The tree state of our repository still needs to be placed in time. That's the
55 job of the commit::
56
57   >>> from dulwich.objects import Commit
58   >>> from time import time
59   >>> commit = Commit()
60   >>> commit.tree = tree.id
61   >>> author = "Your Name <your.email@example.com>"
62   >>> commit.author = commit.committer = author
63   >>> commit.commit_time = commit.author_time = int(time())
64   >>> tz = parse_timezone('-0200')
65   >>> commit.commit_timezone = commit.author_timezone = tz
66   >>> commit.encoding = "UTF-8"
67   >>> commit.message = "Initial commit"
68
69 Note that the initial commit has no parents.
70
71 At this point, the repository is still empty because all operations happen in
72 memory. Let's "commit" it.
73
74   >>> object_store = repo.object_store
75   >>> object_store.add_object(blob)
76
77 Now the ".git/objects" folder contains a first SHA-1 file. Let's continue
78 saving the changes::
79
80   >>> object_store.add_object(tree)
81   >>> object_store.add_object(commit)
82
83 Now the physical repository contains three objects but still has no branch.
84 Let's create the master branch like Git would::
85
86   >>> repo.refs['refs/heads/master'] = commit.id
87
88 The master branch now has a commit where to start, but Git itself would not
89 known what is the current branch. That's another reference::
90
91   >>> repo.refs['HEAD'] = 'ref: refs/heads/master'
92
93 Now our repository is officialy tracking a branch named "master" refering to a
94 single commit.
95
96 Playing again with Git
97 ======================
98
99 At this point you can come back to the shell, go into the "myrepo" folder and
100 type ``git status`` to let Git confirm that this is a regular repository on
101 branch "master".
102
103 Git will tell you that the file "spam" is deleted, which is normal because
104 Git is comparing the repository state with the current working copy. And we
105 have absolutely no working copy using Dulwich because we don't need it at
106 all!
107
108 You can checkout the last state using ``git checkout -f``. The force flag
109 will prevent Git from complaining that there are uncommitted changes in the
110 working copy.
111
112 The file ``spam`` appears and with no surprise contains the same bytes as the
113 blob::
114
115   $ cat spam
116   My file content
117
118 .. attention:: Remember to recreate the repo object when you modify the
119                repository outside of Dulwich!