Sign in Join
Wiki copytemporary

FPC git: what changed

Revision 2 to 3. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11## Git setup
22
33### Git repository location
44
5-The Git repositories are hosted on Gitlab:
6-
7-FPC compiler, RTL, packages and utils are located here:
8-
9-
10-[<https://gitlab.com/freepascal.org/fpc/source>](https://gitlab.com/freepascal.org/fpc/source)
11-
12-The URL to clone the repository is:
5+The Git repositories are hosted on Gitlab:
136
14-
15-[<https://gitlab.com/freepascal.org/fpc/source.git>](https://gitlab.com/freepascal.org/fpc/source.git)
7+FPC compiler, RTL, packages and utils are located here:
168
17- git clone https://gitlab.com/freepascal.org/fpc/source.git
9+<https://gitlab.com/freepascal.org/fpc/source>
1810
19-The Documentation Git repository is here:
11+The URL to clone the repository is:
2012
21-
22-[<https://gitlab.com/freepascal.org/fpc/documentation>](https://gitlab.com/freepascal.org/fpc/documentation)
13+<https://gitlab.com/freepascal.org/fpc/source.git>
14+```
15+git clone https://gitlab.com/freepascal.org/fpc/source.git
16+```
2317
24-The URL to clone the documentation repository is:
18+The Documentation Git repository is here:
2519
26-
27-[<https://gitlab.com/freepascal.org/fpc/documentation.git>](https://gitlab.com/freepascal.org/fpc/documentation.git)
20+<https://gitlab.com/freepascal.org/fpc/documentation>
2821
29- git clone https://gitlab.com/freepascal.org/fpc/documentation.git
22+The URL to clone the documentation repository is:
3023
31-The website Git repository is here:
24+<https://gitlab.com/freepascal.org/fpc/documentation.git>
25+```
26+git clone https://gitlab.com/freepascal.org/fpc/documentation.git
27+```
3228
33-
34-[<https://gitlab.com/freepascal.org/fpc/website>](https://gitlab.com/freepascal.org/fpc/website)
29+The website Git repository is here:
3530
36-The URL to clone the website repository is:
31+<https://gitlab.com/freepascal.org/fpc/website>
3732
38-
39-[<https://gitlab.com/freepascal.org/fpc/website.git>](https://gitlab.com/freepascal.org/fpc/website.git)
33+The URL to clone the website repository is:
4034
41- git clone https://gitlab.com/freepascal.org/fpc/website.git
35+<https://gitlab.com/freepascal.org/fpc/website.git>
36+```
37+git clone https://gitlab.com/freepascal.org/fpc/website.git
38+```
4239
4340### Your identity in git
4441
45-In order for your commits to be recognized, please configure your local (or better yet, global) git installation to use the address linked to your gitlab acccount.
46-
47- git config --global user.email your.email.user@youremail.host
48-
49-This will set your email address for all git repositories you use, and will allow the gitlab interface to correctly link commits to users in its HTML interface.
42+In order for your commits to be recognized, please configure your local (or better yet, global) git installation to use the address linked to your gitlab acccount.
43+```
44+git config --global user.email your.email.user@youremail.host
45+```
5046
51-If you have multiple gitlab (or even github) accounts, you may prefer to set this email only locally:
47+This will set your email address for all git repositories you use, and will allow the gitlab interface to correctly link commits to users in its HTML interface.
5248
53- git config --local user.email your.email.user@youremail.host
49+If you have multiple gitlab (or even github) accounts, you may prefer to set this email only locally:
50+```
51+git config --local user.email your.email.user@youremail.host
52+```
5453
55-this command must be execute in a particular repository, and sets the email address for only that repository.
54+this command must be execute in a particular repository, and sets the email address for only that repository.
5655
5756### HTTP access and credentials
5857
59-If you access the repository using HTTPS, by default, git will ask for the username/password. you can tell git to store them permanently, issue the following command:
60-
61- git config --global credential.helper store
58+If you access the repository using HTTPS, by default, git will ask for the username/password. you can tell git to store them permanently, issue the following command:
59+```
60+git config --global credential.helper store
61+```
6262
63-There are other possibilities for storing this info. More info can be found on
63+There are other possibilities for storing this info. More info can be found on
6464
65-
66-[<https://git-scm.com/book/en/v2/Git-Tools-Credential-Storage>](https://git-scm.com/book/en/v2/Git-Tools-Credential-Storage)
65+<https://git-scm.com/book/en/v2/Git-Tools-Credential-Storage>
6766
6867### Using access tokens
6968
70-You may want to use an access token and HTTPS access, it has some advantages. This is supported by most modern git clients:
69+You may want to use an access token and HTTPS access, it has some advantages. This is supported by most modern git clients:
7170
72-
73-[<https://knasmueller.net/gitlab-authenticate-using-access-token>](https://knasmueller.net/gitlab-authenticate-using-access-token)
71+<https://knasmueller.net/gitlab-authenticate-using-access-token>
7472
75-and here you can see how to do this on gitlab:
73+and here you can see how to do this on gitlab:
7674
77-
78-[<https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html>](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html)
75+<https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html>
7976
80-The advantage of using an access token is that it can be given limited rights on gitlab, for example only accessing a repository. This also means you can easily enable 2FA for your gitlab account.
77+The advantage of using an access token is that it can be given limited rights on gitlab, for example only accessing a repository. This also means you can easily enable 2FA for your gitlab account.
8178
8279### Git mirror on GitHub
8380
84-The GitLab repositories are mirrored on [GitHub](https://github.com/fpc/). Cloning of the sources can be done with the following command
85-
86- git clone https://github.com/fpc/FPCSource.git fpc
87-
88-and for documentation:
81+The GitLab repositories are mirrored on [GitHub](<https://github.com/fpc/>). Cloning of the sources can be done with the following command
82+```
83+git clone https://github.com/fpc/FPCSource.git fpc
84+```
8985
90- git clone https://github.com/fpc/FPCDocumentation.git fpcdocs
86+and for documentation:
87+```
88+git clone https://github.com/fpc/FPCDocumentation.git fpcdocs
89+```
9190
92-In case you want to submit patches (pull requests) it is strongly recommended to use GitLab instead.
91+In case you want to submit patches (pull requests) it is _strongly recommended_ to use GitLab instead.
9392
9493## Branching model
9594
96-In a first stage, the branching model as used in Subversion will be used: fixes done in trunk, and later cherry picked to the fixes branch.
95+In a first stage, the branching model as used in Subversion will be used: fixes done in trunk, and later cherry picked to the fixes branch.
9796
98-At a later stage, the branching model may be changed into one of the many git branching schemes.
97+At a later stage, the branching model may be changed into one of the many git branching schemes.
9998
10099## Windows Git clients
101100
102-On macOS, Linux & BSD, the git command is installed with the system package manager (you must install XCode command line tools on macOS). On Windows, a separate git client must be installed. There are many available, but the following are popular ones:
101+On macOS, Linux & BSD, the git command is installed with the system package manager (you must install XCode command line tools on macOS). On Windows, a separate git client must be installed. There are many available, but the following are popular ones:
103102
104-- Git for windows: a command-line client with a bash shell, so you can copy & paste commands you find on internet:
103+ * **Git** for windows: a command-line client with a bash shell, so you can copy & paste commands you find on internet:
105104
106-
107-[<https://gitforwindows.org/>](https://gitforwindows.org/)
105+<https://gitforwindows.org/>
108106
109-- TortoiseGit integrates with the Windows explorer, much like TortoiseSVN does:
107+ * **TortoiseGit** integrates with the Windows explorer, much like TortoiseSVN does:
110108
111-
112-[<https://tortoisegit.org/>](https://tortoisegit.org/)
109+<https://tortoisegit.org/>
113110
114111if you already have TortoisSVN installed, both can work side-by-side.
115112
116-- Sourcetree is a free client for Windows and macOS:
113+ * **Sourcetree** is a free client for Windows and macOS:
117114
118-
119-[<https://www.sourcetreeapp.com/>](https://www.sourcetreeapp.com/)
115+<https://www.sourcetreeapp.com/>
120116
121117It is made by the people from bitbucket.
122118
123-- Smartgit runs on Windows, Linux and macOS:
119+ * **Smartgit** runs on Windows, Linux and macOS:
124120
125-
126-[<https://www.syntevo.com/smartgit/>](https://www.syntevo.com/smartgit/)
121+<https://www.syntevo.com/smartgit/>
127122
128-- The VSCode and Atom editors have git support built in.
123+ * The VSCode and Atom editors have git support built in.
129124
130125## Concepts and SVN to GIT differences
131126
132-A few "good to know" differences: [[FPC git concepts]].
127+A few "good to know" differences: [[FPC git concepts]].
133128
134129## Common SVN operations in Git
135130
136131### Check out
137132
138-To check out a new copy of a repository is called 'cloning' in git.
139-
140- git clone https://gitlab.com/freepascal.org/testconversion
141-
142-As in subversion, you can give it another name:
133+To check out a new copy of a repository is called 'cloning' in git.
134+```
135+git clone https://gitlab.com/freepascal.org/testconversion
136+```
143137
144- git clone https://gitlab.com/freepascal.org/testconversion myconversion
138+As in subversion, you can give it another name:
139+```
140+git clone https://gitlab.com/freepascal.org/testconversion myconversion
141+```
145142
146-This operation can take a while, the FPC source base is large.
143+This operation can take a while, the FPC source base is large.
147144
148145### Update
149146
150-To update your source code with the changes in the remote repository, is called 'pulling' in git:
151-
152- git pull
153-
154-Note that in difference with subversion, git always updates the whole repository.
155-
156-> **Note:** While git will fetch and apply changes to all *remote* branches with this command, of all *local* branches it will only update the one that's currently checked out (see [[FPC git|ls (listing branches)]] for more information about remote/local branches). To update other local branches, you have to [[FPC git|switch]] to them and either execute `git pull` again, or rebase/merge (will be documented once we decide which strategy to use).
147+To update your source code with the changes in the remote repository, is called 'pulling' in git:
148+```
149+git pull
150+```
157151
158-To keep a commit history which is as linear as possible and avoids merge commits, it is recommended to do a rebase when you pull.
152+Note that in difference with subversion, git always updates the whole repository.
159153
160- git pull --rebase
154+![Light bulb](https://upload.wikimedia.org/wikipedia/commons/d/d8/Nuvola_apps_ktip.png) **Note:** While git will fetch and apply changes to all _remote_ branches with this command, of all _local_ branches it will only update the one that's currently checked out (see [[FPC git|ls (listing branches)]] for more information about remote/local branches). To update other local branches, you have to [[FPC git|switch]] to them and either execute `git pull` again, or rebase/merge (will be documented once we decide which strategy to use).
161155
162-You can make the use of rebase for every pull the default by executing:
156+To keep a commit history which is as linear as possible and avoids merge commits, it is recommended to do a rebase when you pull.
157+```
158+git pull --rebase
159+```
163160
164- git config pull.rebase true
161+You can make the use of rebase for every pull the default by executing:
162+```
163+git config pull.rebase true
164+```
165165
166166### Resolve
167167
168-If you have conflicts in svn after updating or merging, you fix the conflicts and then tell svn everything is fine with the *resolved* command.
168+If you have conflicts in svn after updating or merging, you fix the conflicts and then tell svn everything is fine with the _resolved_ command.
169169
170-In git, conflicts generally occur when [[FPC git|merging]] or when applying [[FPC git|shelved/stashed]] changes.
170+In git, conflicts generally occur when [[FPC git|merging]] or when applying [[FPC git|shelved/stashed]] changes.
171171
172-When conflicts occur, then
172+When conflicts occur, then
173173
174-1. Changes to files that are not in conflict, will be [[FPC git|staged]]
175-2. Changes to files that do conflict will be applied without staging to the working copy (so that a plain [[FPC git|diff]] will only show conflicting changes)
174+ 1. Changes to files that are not in conflict, will be [[FPC git|staged]]
175+ 2. Changes to files that do conflict will be applied without staging to the working copy (so that a plain [[FPC git|diff]] will only show conflicting changes)
176176
177-To resolve conflicts,
177+To resolve conflicts,
178178
179-1. If you want to commit the resolved version of the file, mark it as resolved by [[FPC git|staging/adding]] it as well
180-2. If you want to just get rid of the "both modified" status (= conflicted) without adding the file, use `git reset file`
179+ 1. If you want to commit the resolved version of the file, mark it as resolved by [[FPC git|staging/adding]] it as well
180+ 2. If you want to just get rid of the "both modified" status (= conflicted) without adding the file, use `git reset file`
181181
182-Once all files have been staged or marked as not conflicted, you can commit (only staged files will be committed).
182+Once all files have been staged or marked as not conflicted, you can commit (only staged files will be committed).
183183
184184### add (adding new files)
185185
186-Subversion uses the *add* command to add a file to the versioning system. This is no different in git: If you want to add a file, you must add it first, like this:
187-
188- git add newfile.pas
186+Subversion uses the _add_ command to add a file to the versioning system. This is no different in git: If you want to add a file, you must add it first, like this:
187+```
188+git add newfile.pas
189+```
189190
190-You must then (just as in subversion) still commit this newly added file.
191+You must then (just as in subversion) still commit this newly added file.
191192
192193### rm (removing files)
193194
194-Subversion uses the *rm* command to remove a file from the versioning system. This is no different in git:
195-
196- git rm nolongerneededfile.pas
195+Subversion uses the _rm_ command to remove a file from the versioning system. This is no different in git:
196+```
197+git rm nolongerneededfile.pas
198+```
197199
198-You must then (just as in subversion) still commit this removed file.
200+You must then (just as in subversion) still commit this removed file.
199201
200202### mv (renaming files)
201203
202-Subversion uses the *mv* command to rename a file in the versioning system. This is no different in git:
203-
204- git mv oldfile.pas newfile.pas
205-
206-You must then (just as in subversion) still commit this change.
204+Subversion uses the _mv_ command to rename a file in the versioning system. This is no different in git:
205+```
206+git mv oldfile.pas newfile.pas
207+```
207208
208-As in subversion, you can move one or more files to another directory:
209+You must then (just as in subversion) still commit this change.
209210
210- git mv file1.pas file2.pas somesubdir
211+As in subversion, you can move one or more files to another directory:
212+```
213+git mv file1.pas file2.pas somesubdir
214+```
211215
212216### commit
213217
214-If you have made some changes locally and wish to commit them, this is a 2-step process:
215-
216- git add myfile.pas
217-
218-This schedules the file to be committed (called *staging* in git, so the changes are now *staged*). You can add as many files as you want like this.
219-
220-> **Note:** An easy way to remember this is that svn requires the same for newly added files. Git extends this to all changes, because that way you not only can selectively schedule individual new files for the next commit, but also changes to existing files. The opposite of `git add` is `git reset` (**without** the `--hard` parameter!)
221-
222-> **Note:** To see the changes that have been staged/scheduled for commit, use `git diff --cached`. Plain `git diff` will show local changes that are not (yet) staged.
223-
224-When you are ready to commit what you have staged, you can commit:
218+If you have made some changes locally and wish to commit them, this is a 2-step process:
219+```
220+git add myfile.pas
221+```
225222
226- git commit -m '* Some nice comment telling what you did'
223+This schedules the file to be committed (called _staging_ in git, so the changes are now _staged_). You can add as many files as you want like this.
227224
228-In fact, if you're in a hurry and know you want to commit a file, you can combine the 2 commands;
225+![Light bulb](https://upload.wikimedia.org/wikipedia/commons/d/d8/Nuvola_apps_ktip.png) **Note:** An easy way to remember this is that svn requires the same for newly added files. Git extends this to all changes, because that way you not only can selectively schedule individual new files for the next commit, but also changes to existing files. The opposite of `git add` is `git reset` (**without** the `--hard` parameter!)
229226
230- git commit -m '* Some nice comment telling what you did' myfile.pas
227+![Light bulb](https://upload.wikimedia.org/wikipedia/commons/d/d8/Nuvola_apps_ktip.png) **Note:** To see the changes that have been staged/scheduled for commit, use `git diff --cached`. Plain `git diff` will show local changes that are not (yet) staged.
231228
232-If you are really in a hurry, you can commit all changed files in one fell swoop:
229+When you are ready to commit what you have staged, you can commit:
230+```
231+git commit -m '* Some nice comment telling what you did'
232+```
233233
234- git commit -m '* Some nice comment telling what you did' -a
234+In fact, if you're in a hurry and know you want to commit a file, you can combine the 2 commands;
235+```
236+git commit -m '* Some nice comment telling what you did' myfile.pas
237+```
235238
236-But it is not really recommended to use this, as it will commit *all* changes in your local copy, not just the ones in the current working directory.
239+If you are really in a hurry, you can commit all changed files in one fell swoop:
240+```
241+git commit -m '* Some nice comment telling what you did' -a
242+```
237243
238-At this point, your changes have been saved locally, but have not yet been sent to the remote repository. To do that, you must additionally send the changes to the remote repository. This is called pushing:
244+But it is not really recommended to use this, as it will commit _all_ changes in your local copy, not just the ones in the current working directory.
239245
240- git push
246+At this point, your changes have been saved locally, but have not yet been sent to the remote repository. To do that, you must additionally send the changes to the remote repository. This is called pushing:
247+```
248+git push
249+```
241250
242-That will send all locally committed changes to the server. Obviously only changes that have not yet been sent previously are sent.
251+That will send all locally committed changes to the server. Obviously only changes that have not yet been sent previously are sent.
243252
244253### diff (show changes to working copy)
245254
246-In svn, you can see the changes that have been made but have not yet been committed with *diff*. This is also correct in git:
247-
248- git diff
249-
250-This will show all changes in your working copy ***that are not yet staged*** (scheduled for committing).
251-
252-You can view this for a single file as well:
255+In svn, you can see the changes that have been made but have not yet been committed with _diff_. This is also correct in git:
256+```
257+git diff
258+```
253259
254- git diff myfile.pas
260+This will show all changes in your working copy _**that are not yet staged**_ (scheduled for committing).
255261
256-This will show unstaged changes made to your working copy of **myfile.pas**.
262+You can view this for a single file as well:
263+```
264+git diff myfile.pas
265+```
257266
258-If you have already staged one or more files (i.e. marked for inclusion in the next commit), the above will not show them in the generated diff. If you wish to see the staged changes (and *only* the staged changed), use the *--cached* command-line option:
267+This will show unstaged changes made to your working copy of **myfile.pas**.
259268
260- git diff --cached
269+If you have already staged one or more files (i.e. marked for inclusion in the next commit), the above will not show them in the generated diff. If you wish to see the staged changes (and _only_ the staged changed), use the _\--cached_ command-line option:
270+```
271+git diff --cached
272+```
261273
262274### diff (show changes performed in a commit)
263275
264-In svn, you can see the changes that a commit did through `svn diff -c <revision>`. In git, you use the *show* command instead:
265-
266- git show -p <commit_hash_or_branch_or_tag>
276+In svn, you can see the changes that a commit did through `svn diff -c <revision>`. In git, you use the _show_ command instead:
277+```
278+git show -p <commit_hash_or_branch_or_tag>
279+```
267280
268-If you omit the commit hash, the last commit to the current branch will be shown instead.
281+If you omit the commit hash, the last commit to the current branch will be shown instead.
269282
270283### log (show commits in a branch)
271284
272-In svn, you can see the commits in a branch with `svn log`. The same works in git:
273-
274- git log
275-
276-This will list the commit hashes (the string that git uses to identify commits, similar to revision numbers in svn) followed by the log messages. If you also want to see which files were changed, use
285+In svn, you can see the commits in a branch with `svn log`. The same works in git:
286+```
287+git log
288+```
277289
278- git log --stat
290+This will list the commit hashes (the string that git uses to identify commits, similar to revision numbers in svn) followed by the log messages. If you also want to see which files were changed, use
291+```
292+git log --stat
293+```
279294
280295### ls (listing branches)
281296
282-To get a list of branches in Subversion, you use the 'ls' command with a server URL. By convention, all directories under '/branches' are the names of branches. Branches always exist both on the client(s) and server.
283-
284-In git, branches are formalised as part of the version control system: commands deal specifically with branches rather than with paths that are treated as branches. Additionally, git differentiates between **remote branches** (branches that exist in the repository that you cloned, i.e., in this case on the gitlab server), and **local branches** (branches that you created on your machine after cloning). The repository that you cloned is referenced using the alias "origin" by default, and the names of remote branches are prepended by this alias.
285-
286-The list of local branches can be obtained using:
297+To get a list of branches in Subversion, you use the 'ls' command with a server URL. By convention, all directories under '/branches' are the names of branches. Branches always exist both on the client(s) and server.
287298
288- git branch
299+In git, branches are formalised as part of the version control system: commands deal specifically with branches rather than with paths that are treated as branches. Additionally, git differentiates between **remote branches** (branches that exist in the repository that you cloned, i.e., in this case on the gitlab server), and **local branches** (branches that you created on your machine after cloning). The repository that you cloned is referenced using the alias "origin" by default, and the names of remote branches are prepended by this alias.
289300
290-By default, the only local branch you will have is `main`, which corresponds to svn trunk. This local branch is automatically created when performing the initial clone operation.
301+The list of local branches can be obtained using:
302+```
303+git branch
304+```
291305
292-The list of remote branches can be obtained using:
306+By default, the only local branch you will have is `main`, which corresponds to svn trunk. This local branch is automatically created when performing the initial clone operation.
293307
294- git branch -r
308+The list of remote branches can be obtained using:
309+```
310+git branch -r
311+```
295312
296-By default, the remote branches are the branches that exist in the repository on the gitlab server, whose alias is "origin". The local `main` branch automatically *tracks* (~ is linked to) the remote `origin/main` branch. Because of this tracking, executing `git pull` resp. `git push` commands while you have your local `main` branch checked out will synchronise the two from resp. to gitlab. See [[FPC git|switch]] on how to create more local branches and how to link them to remote branches.
313+By default, the remote branches are the branches that exist in the repository on the gitlab server, whose alias is "origin". The local `main` branch automatically _tracks_ (~ is linked to) the remote `origin/main` branch. Because of this tracking, executing `git pull` resp. `git push` commands while you have your local `main` branch checked out will synchronise the two from resp. to gitlab. See [[FPC git|switch]] on how to create more local branches and how to link them to remote branches.
297314
298-> **Note:** While git always downloads all branches and their commits by default when cloning or pulling and while you can use their content without a network connection, you cannot directly work on remote branches (since they're remote and not local). Instead, you have to create a local branch that "tracks" this remote branch.
315+![Light bulb](https://upload.wikimedia.org/wikipedia/commons/d/d8/Nuvola_apps_ktip.png) **Note:** While git always downloads all branches and their commits by default when cloning or pulling and while you can use their content without a network connection, you cannot directly work on remote branches (since they're remote and not local). Instead, you have to create a local branch that "tracks" this remote branch.
299316
300-> **Note:** Do not directly checkout a remote branch. That will put you in a so-called "detached HEAD" state: your working copy will contain the contents from that branch, but you can't commit anything as you can only commit to local branches. You can get out of a "detached HEAD" state by simply checking out another branch.
317+![Light bulb](https://upload.wikimedia.org/wikipedia/commons/d/d8/Nuvola_apps_ktip.png) **Note:** Do not directly checkout a remote branch. That will put you in a so-called "detached HEAD" state: your working copy will contain the contents from that branch, but you can't commit anything as you can only commit to local branches. You can get out of a "detached HEAD" state by simply checking out another branch.
301318
302319### copy (creating a branch)
303320
304-To create a branch from the current working directory situation, you can create a branch like this:
305-
306- git branch mybugfix
307-
308-this will create a branch mybugfix from the currently checked out branch at the current commit. But it does not yet make this the active branch.
309-
310-You need to check out the newly made branch first:
321+To create a branch from the current working directory situation, you can create a branch like this:
322+```
323+git branch mybugfix
324+```
311325
312- git checkout mybugfix
326+this will create a branch mybugfix from the currently checked out branch at the current commit. But it does not yet make this the active branch.
313327
314-The two operations can also be combined with one command:
328+You need to check out the newly made branch first:
329+```
330+git checkout mybugfix
331+```
315332
316- git checkout -b mybugfix
333+The two operations can also be combined with one command:
334+```
335+git checkout -b mybugfix
336+```
317337
318338### switch (checking out a branch)
319339
320-To switch to an existing *local* branch **mybugfix**, you can use the checkout command:
321-
322- git checkout mybugfix
323-
324-this will check out branch mybugfix. If there are any uncommitted changes which would cause a conflict, git will refuse the checkout.
325-
326-To switch to a *remote* branch \`mybugfix2\`, which does not exist yet locally, you can also use the checkout command:
340+To switch to an existing _local_ branch **mybugfix** , you can use the checkout command:
341+```
342+git checkout mybugfix
343+```
327344
328- git checkout mybugfix2
345+this will check out branch mybugfix. If there are any uncommitted changes which would cause a conflict, git will refuse the checkout.
329346
330-this will check out branch mybugfix2 and automatically set it up to track the remote branch. Here again, if there are any uncommitted changes which would cause a conflict, git will refuse the checkout.
347+
331348
332-Note that if the branch does not exist remotely, this will simply create a new branch locally. It is better to be explicit:
349+To switch to a _remote_ branch `mybugfix2`, which does not exist yet locally, you can also use the checkout command:
350+```
351+git checkout mybugfix2
352+```
333353
334- git checkout -b mybugfix2 --track origin/mybugfix2
354+this will check out branch mybugfix2 and automatically set it up to track the remote branch. Here again, if there are any uncommitted changes which would cause a conflict, git will refuse the checkout.
335355
336-If you created a branch locally which does not yet exist on the server, made some modifications, and you wish to push this branch to the server, you must tell this to git when pushing:
356+Note that if the branch does not exist remotely, this will simply create a new branch locally. It is better to be explicit:
357+```
358+git checkout -b mybugfix2 --track origin/mybugfix2
359+```
337360
338- git push -u origin/mybugfix mybugfix
361+If you created a branch locally which does not yet exist on the server, made some modifications, and you wish to push this branch to the server, you must tell this to git when pushing:
362+```
363+git push -u origin/mybugfix mybugfix
364+```
339365
340-the **-u origin/mybugfix** tells git all it needs to know to connect the local with the remote branch.
366+the **-u origin/mybugfix** tells git all it needs to know to connect the local with the remote branch.
341367
342368### revert
343369
344370#### Revert the entire working tree
345371
346-If you have made some changes locally and wish to undo them, you can do a *hard reset* in git:
347-
348- git reset --hard
372+If you have made some changes locally and wish to undo them, you can do a _hard reset_ in git:
373+```
374+git reset --hard
375+```
349376
350-This will undo any changes you made in the entire checkout, including any [[FPC git|staged changes]].
377+This will undo any changes you made in the entire checkout, including any [[FPC git|staged changes]].
351378
352379#### Revert changes to specific files/directories
353380
354-You cannot undo changes to individual files with `git reset --hard`. Instead, use
355-
356- git checkout <pathspec>
381+You cannot undo changes to individual files with `git reset --hard`. Instead, use
382+```
383+git checkout <pathspec>
384+```
357385
358-`pathspec` can be any combination of files and directories. Note that if the files had [[FPC git|staged changes]], this command will restore the staged version rather than the last committed version.
386+`pathspec` can be any combination of files and directories. Note that if the files had [[FPC git|staged changes]], this command will restore the staged version rather than the last committed version.
359387
360-> **Note:** At first sight, the git `checkout` command replaces an arbitrary collection of svn commands. The reason is that its operation is defined as "update the files in my working tree to match the specified staged/committed version of the files". So switching to a branch corresponds to getting the version of the files from that branch, while reverting corresponds to the latest version of the files from the current branch.
388+![Light bulb](https://upload.wikimedia.org/wikipedia/commons/d/d8/Nuvola_apps_ktip.png) **Note:** At first sight, the git `checkout` command replaces an arbitrary collection of svn commands. The reason is that its operation is defined as "update the files in my working tree to match the specified staged/committed version of the files". So switching to a branch corresponds to getting the version of the files from that branch, while reverting corresponds to the latest version of the files from the current branch.
361389
362390### merge (merging the changes in 2 branches)
363391
364-To merge changes in 2 branches, you use the *merge* command. If we want to merge the changes in *mybugfix* to *fixes* then we do:
365-
366- git checkout fixes
392+To merge changes in 2 branches, you use the _merge_ command. If we want to merge the changes in _mybugfix_ to _fixes_ then we do:
393+```
394+git checkout fixes
367395 git merge mybugfix
396+```
368397
369398### blame (check who made modifications)
370399
371-To see who changes what line (and in what commit) svn offers you the 'blame' command. The same command exists in git.
372-
373- git blame yourfile.pas
400+To see who changes what line (and in what commit) svn offers you the 'blame' command. The same command exists in git.
401+```
402+git blame yourfile.pas
403+```
374404
375405### status (check status of files)
376406
377-To see whether there are any changed files in your working repository, svn offers the 'status' command. The same command exists in git.
378-
379- git status
380-
381-will present you with all changed, staged and new files in the repository.
407+To see whether there are any changed files in your working repository, svn offers the 'status' command. The same command exists in git.
408+```
409+git status
410+```
382411
383-If you want only the status of files below a certain directory, you can specify the name of the directory. So to get the changes in the current working directory (or below) that would be:
412+will present you with all changed, staged and new files in the repository.
384413
385- git status .
414+If you want only the status of files below a certain directory, you can specify the name of the directory. So to get the changes in the current working directory (or below) that would be:
415+```
416+git status .
417+```
386418
387-will present you with all changed, staged and new files in the current directory. This is the default behaviour of svn.
419+will present you with all changed, staged and new files in the current directory. This is the default behaviour of svn.
388420
389421### shelve (temporarily undo changes)
390422
391-Subversion has an (experimental) feature that allows to temporarily set aside changes to your working copy : shelve. This feature exists since a long time in git and is called stash:
392-
393- git stash
394-
395-will set aside any changes to the working copy, and restore the working copy to the state it would be in if you did a 'git pull' (or svn update).
396-
397-To reapply the changes you set aside to the working copy, and to remove them from the list of stashes at the same time, you can execute the following command:
423+Subversion has an (experimental) feature that allows to temporarily set aside changes to your working copy : shelve. This feature exists since a long time in git and is called stash:
424+```
425+git stash
426+```
398427
399- git stash pop
428+will set aside any changes to the working copy, and restore the working copy to the state it would be in if you did a 'git pull' (or svn update).
400429
401-If any conflicts occur, you can
430+To reapply the changes you set aside to the working copy, and to remove them from the list of stashes at the same time, you can execute the following command:
431+```
432+git stash pop
433+```
402434
403-- resolve them, or
404-- use [[FPC git|git reset --hard]] to revert all files again
435+If any conflicts occur, you can
405436
406-In either case, the stash will not be touched when conflicts occurred while applying it. If you still with to remove it, you can do so with
437+ * resolve them, or
438+ * use [[FPC git|git reset --hard]] to revert all files again
407439
408- git stash drop
440+In either case, the stash will not be touched when conflicts occurred while applying it. If you still with to remove it, you can do so with
441+```
442+git stash drop
443+```
409444
410445### info (get working dir and server info)
411446
412-In subversion, you can get information about the current working directory and remote server configuration using *svn info*. Since git is a distributed system, no direct equivalent of the info command exists: there is no single server, and the revision number as known in subversion does not exist.
413-
414-The following script attempts to display similar information as the *svn info* command:
447+In subversion, you can get information about the current working directory and remote server configuration using _svn info_. Since git is a distributed system, no direct equivalent of the info command exists: there is no single server, and the revision number as known in subversion does not exist.
415448
416-``` bash
449+The following script attempts to display similar information as the _svn info_ command:
450+```
417451#!/bin/bash
418-
419-# author: Duane Johnson
420-# email: duane.johnson@gmail.com
421-# date: 2008 Jun 12
422-# license: MIT
423-#
424-# Based on discussion at http://kerneltrap.org/mailarchive/git/2007/11/12/406496
425-
426-pushd . >/dev/null
427-
428-# Find base of git directory
429-while [ ! -d .git ] && [ ! `pwd` = "/" ]; do cd ..; done
430-
431-# Show various information about this git directory
432-if [ -d .git ]; then
433- echo "== Remote URL: `git remote -v`"
434-
435- echo "== Remote Branches: "
436- git branch -r
437- echo
438-
439- echo "== Local Branches:"
440- git branch
441- echo
442-
443- echo "== Configuration (.git/config)"
444- cat .git/config
445- echo
446-
447- echo "== Most Recent Commit"
448- git --no-pager log -n1
449- echo
450-
451- echo "Type 'git log' for more commits, or 'git show' for full commit details."
452-else
453- echo "Not a git repository."
454-fi
455-
456-popd >/dev/null
452+
453+ # author: Duane Johnson
454+ # email: duane.johnson@gmail.com
455+ # date: 2008 Jun 12
456+ # license: MIT
457+ #
458+ # Based on discussion at http://kerneltrap.org/mailarchive/git/2007/11/12/406496
459+
460+ pushd . >/dev/null
461+
462+ # Find base of git directory
463+ while [ ! -d .git ] && [ ! `pwd` = "/" ]; do cd ..; done
464+
465+ # Show various information about this git directory
466+ if [ -d .git ]; then
467+ echo "== Remote URL: `git remote -v`"
468+
469+ echo "== Remote Branches: "
470+ git branch -r
471+ echo
472+
473+ echo "== Local Branches:"
474+ git branch
475+ echo
476+
477+ echo "== Configuration (.git/config)"
478+ cat .git/config
479+ echo
480+
481+ echo "== Most Recent Commit"
482+ git --no-pager log -n1
483+ echo
484+
485+ echo "Type 'git log' for more commits, or 'git show' for full commit details."
486+ else
487+ echo "Not a git repository."
488+ fi
489+
490+ popd >/dev/null
457491```
458492
459-Note that this script will also work in the Windows environment if you have the windows git client installed, because it comes with a minimal unix environment.
493+Note that this script will also work in the Windows environment if you have the windows git client installed, because it comes with a minimal unix environment.
460494
461495### bisect'ing
462496
463-When it is known that for example "make cycle" worked for a certain revision but it is broken with the current head of main, one can do a manual "binary search" to find the broken revision. With git, this can be done fully automatically using the git command `bisect`:
464-
465- # change into a directory with a fpc git repository
497+When it is known that for example "make cycle" worked for a certain revision but it is broken with the current head of main, one can do a manual "binary search" to find the broken revision. With git, this can be done fully automatically using the git command `bisect`:
498+```
499+# change into a directory with a fpc git repository
466500 git bisect start # tell git that we start bisecting
467501 git bisect bad # mark the currently checkout commit as bad
468502 git checkout 12345678 # checkout a commit you know that it is good
469503 git bisect good # tell git that at this commit everything is good
470-
471-During this command, git checks out the commit it wants to know if it is good or bad. In case of a broken "make cycle" one can run this now and tell git by "git bisect good" or "git bisect bad" what the status of the commit is. Then git will automatically checkout the next commit to test. After several tests, git will tell which commit that one is which broke "make cycle". As this is a tedious task, the search can be also automated (Unix shell):
504+```
472505
473- git bisect run sh -c 'cd $PWD/compiler && make cycle'
506+During this command, git checks out the commit it wants to know if it is good or bad. In case of a broken "make cycle" one can run this now and tell git by "git bisect good" or "git bisect bad" what the status of the commit is. Then git will automatically checkout the next commit to test. After several tests, git will tell which commit that one is which broke "make cycle". As this is a tedious task, the search can be also automated (Unix shell):
507+```
508+git bisect run sh -c 'cd $PWD/compiler && make cycle'
509+```
474510
475-git runs the passed command and depending on the result value, the commit will be marked as good (0) or bad (1 to 127, 255 tells git to abort search). git continues to run the command till it finds the commit which breaks things.
511+git runs the passed command and depending on the result value, the commit will be marked as good (0) or bad (1 to 127, 255 tells git to abort search). git continues to run the command till it finds the commit which breaks things.
476512
477513### file properties (EOL handling etc.)
478514
479-Subversion allows you to set some properties on files. There are 'reserved' properties that svn itself uses, for example to handle EOL handling and file type. Because git operates on diffs and not on files, no similar concept exists.
480-
481-However, git does allow you to set global or local attributes for classes of files. These are in the *.gitattributes* file. That file should be located in the root of your repository, and can contain some attributes. For example:
515+Subversion allows you to set some properties on files. There are 'reserved' properties that svn itself uses, for example to handle EOL handling and file type. Because git operates on diffs and not on files, no similar concept exists.
482516
483- * text=auto
484- *.txt text
485- *.vcproj text eol=crlf
486- *.sh text eol=lf
487- *.jpg -text
517+However, git does allow you to set global or local attributes for classes of files. These are in the _.gitattributes_ file. That file should be located in the root of your repository, and can contain some attributes. For example:
518+```
519+* text=auto
520+ *.txt text
521+ *.vcproj text eol=crlf
522+ *.sh text eol=lf
523+ *.jpg -text
524+```
488525
489-This is a regular file which you can (and must) add with *git add* so it is saved for all users.
526+This is a regular file which you can (and must) add with _git add_ so it is saved for all users.
490527
491528### cherry picking
492529
493-To copy one commit from branch to another, cherry picking can be used, checkout the branch where the commit shall be added and execute:
494-
495- git cherry-pick -x <hash of commit>
496-
497-If this operation causes a conflict, fix it and continue the operation with:
498-
499- git cherry-pick --continue
530+To copy one commit from branch to another, cherry picking can be used, checkout the branch where the commit shall be added and execute:
531+```
532+git cherry-pick -x <hash of commit>
533+```
500534
501-To track which commits are cherry picked, make sure to always use the option `-x`. This appends a small note to the commit message containing the hash of the cherry-picked commit.
535+If this operation causes a conflict, fix it and continue the operation with:
536+```
537+git cherry-pick --continue
538+```
502539
503-In case you want to abort the cherry picking e.g. because of too many conflicts, execute
540+To track which commits are cherry picked, make sure to always use the option `-x`. This appends a small note to the commit message containing the hash of the cherry-picked commit.
504541
505- git cherry-pick --abort
542+In case you want to abort the cherry picking e.g. because of too many conflicts, execute
543+```
544+git cherry-pick --abort
545+```
506546
507547### Managing the FPC fixes branch
508548
509-So far, FPC uses a developement model which is sometimes called the "ghetto development model". Patches battle out in the main branch if they are good and if they are good, they are ported to the fixes branch from which releases are created. This development model is not naturally supported by git but can be implemented based on cherry-picking. To make tracking of cherry picks easier, `git cherry-pick` must be called with `-x`. Furthermore, only one commit at once may be cherry-pick.
510-
511-Example:
549+So far, FPC uses a developement model which is sometimes called the "ghetto development model". Patches battle out in the main branch if they are good and if they are good, they are ported to the fixes branch from which releases are created. This development model is not naturally supported by git but can be implemented based on cherry-picking. To make tracking of cherry picks easier, `git cherry-pick` must be called with `-x`. Furthermore, only one commit at once may be cherry-pick.
512550
513-``` bash
551+Example:
552+```
514553# change to the top-level of a clone of the FPC Source repository
515-
516-git checkout fixes_3_2 # switch to/checkout out the fixes branches, if you did not do so before
517-git pull # ensure fixes_3_2 is up-to-date
518-git cherry-pick -x 12345678 # 12345678 is the hash (can be a short or full hash) of the commit to be cherry picked to fixes
519-git push # push the change to the remote repository
554+
555+ git checkout fixes_3_2 # switch to/checkout out the fixes branches, if you did not do so before
556+ git pull # ensure fixes_3_2 is up-to-date
557+ git cherry-pick -x 12345678 # 12345678 is the hash (can be a short or full hash) of the commit to be cherry picked to fixes
558+ git push # push the change to the remote repository
520559```
521560
522-For conflict resolution, see section about cherry picking.
523-
524-To make things a little bit more easy, to get more information in case of conflits and avoid to forget `-x`, use a script `gcp` like:
561+For conflict resolution, see section about cherry picking.
525562
526-``` bash
563+To make things a little bit more easy, to get more information in case of conflits and avoid to forget `-x`, use a script `gcp` like:
564+```
527565#!/usr/bin/env bash
528-git show --name-only $1
529-git cherry-pick -x $1 || exit 255
566+ git show --name-only $1
567+ git cherry-pick -x $1 || exit 255
530568```
531569
532-> **Note:** Always cherry pick to fixes with -x for tracking and cherry pick only one commit at once.
570+![Light bulb](https://upload.wikimedia.org/wikipedia/commons/d/d8/Nuvola_apps_ktip.png) **Note:** Always cherry pick to fixes with -x for tracking and cherry pick only one commit at once.
533571
534-To figure out which hashes are eliglibe (i.e. not yet cherry picked) for cherry picking, use a script like <https://gitlab.com/freepascal.org/fpc/merging/-/blob/main/findeligible> This script is comparable complicated as it takes also merges from svn times into account. A regularily updated list of eliglible commits can be found at: <https://gitlab.com/freepascal.org/fpc/merging/-/blob/main/eligible.log?expanded=true&viewer=simple>
572+To figure out which hashes are eliglibe (i.e. not yet cherry picked) for cherry picking, use a script like <https://gitlab.com/freepascal.org/fpc/merging/-/blob/main/findeligible> This script is comparable complicated as it takes also merges from svn times into account. A regularily updated list of eliglible commits can be found at: [https://gitlab.com/freepascal.org/fpc/merging/-/blob/main/eligible.log?expanded=true&viewer=simple](<https://gitlab.com/freepascal.org/fpc/merging/-/blob/main/eligible.log?expanded=true&viewer=simple>)
535573
536574#### Mass cherry picking
537575
538-If you have a list of commits identified by their hashes in a file, they can be cherry picked using the script `gcp` from above like:
539-
540-``` bash
576+If you have a list of commits identified by their hashes in a file, they can be cherry picked using the script `gcp` from above like:
577+```
541578xargs -n 1 gcp < filewithhashes
542579```
543580
544-Using the script from above is important because xargs only stops if the called program returns 255. So in case of a cherry pick conflict, the command aborts, one can fix the conflict, remove the already cherry picked commits from `filewithwith` and continue.
545-
546-A file with svn revisions can be converted easily to a list of hashes by something like:
581+Using the script from above is important because xargs only stops if the called program returns 255. So in case of a cherry pick conflict, the command aborts, one can fix the conflict, remove the already cherry picked commits from `filewithwith` and continue.
547582
548-``` bash
583+A file with svn revisions can be converted easily to a list of hashes by something like:
584+```
549585cat filewithrevs | xargs -n 1 git log --grep='trunk@{}' --format='%H' > filewithhashes
550586```
551587
552588#### Submitting a request to merge/cherry-pick a certain commit to fixes
553589
554-Using Gitlab allows to have a defined procedure to merge or actually cherry-pick a certain commit from main(/trunk) to fixes.
590+Using Gitlab allows to have a defined procedure to merge or actually cherry-pick a certain commit from main(/trunk) to fixes.
555591
556-1. Login to Gitlab
557-2. Open the commit in Gitlab
558-3. Click the Options button at the upper right corner and select Cherry-pick
559-4. Choose the latest fixes branch (fixes_3_2 at the time of writing) in the "Pick into branch" field
560-5. Click Cherry-pick, if the commit cannot be cherry-picked due to textual conflicts, you get an error in this step. Possible solutions are:
561- 1. Find the commit which needs to be cherry-picked before the current one to get proper textual merging and submit this cherry-pick request first
562- 2. Cherry-pick the commit in a local clone of the respository and submit a merge request against this newly created commit.
563-6. Do no change anything on the next page, just click Create merge request
592+ 1. Login to Gitlab
593+ 2. Open the commit in Gitlab
594+ 3. Click the Options button at the upper right corner and select Cherry-pick
595+ 4. Choose the latest fixes branch (fixes_3_2 at the time of writing) in the "Pick into branch" field
596+ 5. Click Cherry-pick, if the commit cannot be cherry-picked due to textual conflicts, you get an error in this step. Possible solutions are:
597+ 1. Find the commit which needs to be cherry-picked before the current one to get proper textual merging and submit this cherry-pick request first
598+ 2. Cherry-pick the commit in a local clone of the respository and submit a merge request against this newly created commit.
599+ 6. Do no change anything on the next page, just click Create merge request
564600
565601## Submitting merge requests
566602
567-A big advantage of a distributed version control system is that you can have your own private repository. So you can fully version your work without any access to the pristine repository and when you are ready, you can submit a so-called merge request (MR) to get your work into the official repository.
603+A big advantage of a distributed version control system is that you can have your own private repository. So you can fully version your work without any access to the pristine repository and when you are ready, you can submit a so-called merge request (MR) to get your work into the official repository.
568604
569-The workflow is as follows:
605+The workflow is as follows:
570606
571-1. Login to GitLab
572-2. Go to the repository of the project you want to work on, e.g. FPC Source: <https://gitlab.com/freepascal.org/fpc/source>
573-3. Click Fork at the upper right corner and choose the settings as you like in the following dialog, then click Fork at the bottom. GitLab creates now a full copy of the chosen repository.
574-4. Clone the newly create repository to your machine by getting the URL from the Clone button at the upper right corner of the respository's page on GitLab (e.g. `git clone `[`https://gitlab.com/YourUsername/fpcsource.git`](https://gitlab.com/YourUsername/fpcsource.git)).
575-5. Create a new branch for your work: `git checkout -b myfeature`
576-6. Now do your work: change, commit, change, etc.
577-7. When you are ready, push your branch with `git push origin` into your private repository on GitLab. At this point GitLab shows you already a link how to submit the changes as a merge request to the official/pristine repository. Click the link and follow the instructions.
578-8. If you want to automatically keep your fork up to date with the pristine repository, go to Settings -\> Repository -\> Mirroring repositories and fill in the required fields as described in the [GitLab docs](https://docs.gitlab.com/ee/user/project/repository/mirror/index.html).
607+ 1. Login to GitLab
608+ 2. Go to the repository of the project you want to work on, e.g. FPC Source: <https://gitlab.com/freepascal.org/fpc/source>
609+ 3. Click Fork at the upper right corner and choose the settings as you like in the following dialog, then click Fork at the bottom. GitLab creates now a full copy of the chosen repository.
610+ 4. Clone the newly create repository to your machine by getting the URL from the Clone button at the upper right corner of the respository's page on GitLab (e.g. `git clone <https://gitlab.com/YourUsername/fpcsource.git>`).
611+ 5. Create a new branch for your work: `git checkout -b myfeature`
612+ 6. Now do your work: change, commit, change, etc.
613+ 7. When you are ready, push your branch with `git push origin` into your private repository on GitLab. At this point GitLab shows you already a link how to submit the changes as a merge request to the official/pristine repository. Click the link and follow the instructions.
614+ 8. If you want to automatically keep your fork up to date with the pristine repository, go to Settings -> Repository -> Mirroring repositories and fill in the required fields as described in the [GitLab docs](<https://docs.gitlab.com/ee/user/project/repository/mirror/index.html>).
579615
580616Of course, it is possible work with more than one remote repository in a local one. I.e. push/pull changes from and to your own private one and pull from the official repository. This would go to far for this wiki, have a look at <https://git-scm.com/book/en/v2/Git-Basics-Working-with-Remotes> instead.
581617
582618---
583-*From the Free Pascal wiki, page "FPC git", as it stood on 2022-03-06 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
584-Category: Version Control
619+*From the Free Pascal wiki, page "FPC git", as the Internet Archive kept it on 2025-11-26, last changed on 2024-11-06. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history