Обговорення
Останнє оновлення 2024-06-18 | Редагувати цю сторінку
Поширені запитання
People often have questions about Git beyond the scope of the core material. Студентам, які завершили решту уроків, може бути корисно розглянути наступні теми.
Зауважте, що оскільки цей матеріал не є обов’язковим для базового використання Git, він не буде розглянутий інструктором.
Додаткові налаштування Git
Під час Налаштування Git, ми
використовували git config --global
, щоб встановити деякі
параметри за замовчуванням для Git. It turns out that these
configuration options get stored in your home directory in a plain text
file called .gitconfig
.
ВИХІД
[user]
name = Vlad Dracula
email = vlad@tran.sylvan.ia
[color]
ui = true
[core]
editor = nano
This file can be opened in your preferred text editor. (Note that it
is recommended to continue using the git config
command, as
this helps avoid introducing syntax errors.)
Eventually, you will want to start customizing Git’s behaviour. Це
можна зробити, додавши більше записів до вашого .gitconfig
.
The available options are described in the manual:
Зокрема, вам може знадобитися додати псевдоніми. Це щось на кшталт
скорочень для довших команд Git. Наприклад, якщо вам набридло постійно
вводити git checkout
, ви можете виконати команду:
Now if we return to the example from Exploring History where we ran:
we could now instead type:
Стилізація журналу Git
A good target for customization is output from the log. The default log is quite verbose but gives no graphical hints such as information about which commits were done locally and which were pulled from remotes.
You can use git log --help
and
git config --help
to look for different ways to change the
log output. Try the following commands and see what effect they
have:
BASH
$ git config --global alias.lg "log --graph"
$ git config --global log.abbrevCommit true
$ git config --global format.pretty oneline
$ git lg
If you don’t like the effects, you can undo them with:
BASH
$ git config --global --unset alias.lg
$ git config --global --unset log.abbrevCommit
$ git config --global --unset format.pretty
Скасування змін конфігурації Git
Ви можете використовувати опцію --unset
для видалення
небажаних параметрів з .gitconfig
. Another way to roll back
changes is to store your .gitconfig
using Git.
For hints on what you might want to configure, go to GitHub and search for “gitconfig”. Ви знайдете сотні репозиторіїв, у яких люди зберегли свої власні файли конфігурації Git. Sort them by the number of stars and have a look at the top few. If you find some you like, please check that they’re covered by an open source license before you clone them.
Нетекстові файли
Recall when we discussed Conflicts there was a challenge that asked, “What does Git do when there is a conflict in an image or some other non-textual file that is stored in version control?”
We will now revisit this in more detail.
Many people want to version control non-text files, such as images, PDFs and Microsoft Office or LibreOffice documents. It is true that Git can handle these filetypes (which fall under the banner of “binary” file types). However, just because it can be done doesn’t mean it should be done.
Much of Git’s magic comes from being able to do line-by-line comparisons (“diffs”) between files. This is generally easy for programming source code and marked up text. For non-text files, a diff can usually only detect that the files have changed but can’t say how or where.
This has various impacts on Git’s performance and will make it difficult to compare different versions of your project.
For a basic example to show the difference it makes, we’re going to go see what would have happened if Dracula had tried using outputs from a word processor instead of plain text.
Create a new directory and go into it:
Use a program such as Microsoft Word or LibreOffice Writer to create a new document. Enter the same text that we began with before:
ВИХІД
Cold and dry, but everything is my favorite color
Save the document into the planets-nontext
directory
with the name of mars.doc
. Back in the terminal, run the
usual commands for setting up a new Git repository:
Then make the same changes to mars.doc
that we (or Vlad)
previously made to mars.txt
.
ВИХІД
Cold and dry, but everything is my favorite color
The two moons may be a problem for Wolfman
Save and close the word processor. Now see what Git thinks of your changes:
ВИХІД
diff --git a/mars.doc b/mars.doc
index 53a66fd..6e988e9 100644
Binary files a/mars.doc and b/mars.doc differ
Compare this to the earlier git diff
obtained when using
text files:
ВИХІД
diff --git a/mars.txt b/mars.txt
index df0654a..315bf3a 100644
--- a/mars.txt
+++ b/mars.txt
@@ -1 +1,2 @@
Cold and dry, but everything is my favorite color
+The two moons may be a problem for Wolfman
Notice how plain text files give a much more informative diff. You can see exactly which lines changed and what the changes were.
An uninformative git diff
is not the only consequence of
using Git on binary files. However, most of the other problems boil down
to whether or not a good diff is possible.
This isn’t to say you should never use Git on binary files. A rule of thumb is that it’s OK if the binary file won’t change very often, and if it does change, you don’t care about merging in small differences between versions.
We’ve already seen how a word processed report will fail this test.
An example that passes the test is a logo for your organization or
project. Even though a logo will be stored in a binary format such as
jpg
or png
, you can expect it will remain
fairly static through the lifetime of your repository. On the rare
occasion that branding does change, you will probably just want to
replace the logo completely rather than merge little differences in.
Removing a File
Adding and modifying files are not the only actions one might take when working on a project. It might be required to remove a file from the repository.
Create a new file for the planet Nibiru:
Now add to the repository like you have learned earlier:
ВИХІД
On branch main
nothing to commit, working tree clean
Nibiru is not a real planet. That was a silly idea. Let us remove it from the disk and let Git know about it:
ВИХІД
On branch main
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
deleted: nibiru.txt
The change has been staged. Now commit the removal, and remove the file from the repository itself. Note that the file will be removed in the new commit. The previous commit will still have the file, if you were to retrieve that specific commit.
Removing a File with Unix
Sometimes we might forget to remove the file through Git. If you
removed the file with Unix rm
instead of using
git rm
, no worries, Git is smart enough to notice the
missing file. Let us recreate the file and commit it again.
BASH
$ echo "This is another name for fake planet X" > nibiru.txt
$ git add nibiru.txt
$ git commit -m 'adding nibiru again'
Now we remove the file with Unix rm
:
ВИХІД
On branch main
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
deleted: nibiru.txt
no changes added to commit (use "git add" and/or "git commit -a")
See how Git has noticed that the file nibiru.txt
has
been removed from the disk. The next step is to “stage” the removal of
the file from the repository. This is done with the command
git rm
just as before.
ВИХІД
On branch main
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
deleted: nibiru.txt
The change that was made in Unix has now been staged and needs to be committed.
Renaming a File
Another common change when working on a project is to rename a file.
Create a file for the planet Krypton:
Add it to the repository:
We all know that Superman moved to Earth. Not that he had much choice. Now his home planet is Earth.
Rename the file krypton.txt
to earth.txt
with Git:
ВИХІД
On branch main
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
renamed: krypton.txt -> earth.txt
The final step is commit our change to the repository:
Renaming a File with Unix
If you forgot to use Git and you used Unix mv
instead of
git mv
, you will have a touch more work to do but Git will
be able to deal with it. Let’s try again renaming the file, this time
with Unix mv
. First, we need to recreate the
krypton.txt
file:
BASH
$ echo "Superman's home planet" > krypton.txt
$ git add krypton.txt
$ git commit -m 'Adding planet Krypton again.'
Let us rename the file and see what Git can figured out by itself:
ВИХІД
On branch main
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
deleted: krypton.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
earth.txt
no changes added to commit (use "git add" and/or "git commit -a")
Git has noticed that the file krypton.txt
has
disappeared from the file system and a new file earth.txt
has showed up.
Add those changes to the staging area:
ВИХІД
On branch main
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
renamed: krypton.txt -> earth.txt
Notice how Git has now figured out that the krypton.txt
has not disappeared - it has simply been renamed.
The final step, as before, is to commit our change to the repository:
Further .gitignore concepts
For additional documentation on .gitignore, please reference the official git documentation.
In the ignore exercise, learners were presented with two variations of ignoring nested files. Depending on the organization of your repository, one may suit your needs over another. Keep in mind that the way that Git travels along directory paths can be confusing.
Sometimes the **
pattern comes in handy, too, which
matches multiple directory levels. E.g. **/results/plots/*
would make git ignore the results/plots
directory in any
root directory.
Ignoring Nested Files: Challenge Problem
To do this, your .gitignore would look like this:
ВИХІД
*.csv # ignore the .csv files
results/* # ignore the files in the results directory
!results/data/ # do not ignore the files in results/data
!results/data/* # do not ignore the .csv files in reults/data