diff --git a/README.md b/README.md
index 608eadb1e1ba705067da8da56d2fc4c64d3296cf..74febdd6ae84268a313e5763a327787456a2d6e3 100644
--- a/README.md
+++ b/README.md
@@ -12,11 +12,12 @@ Use docker image `duniter/gitbot:master`.
 
 The configuration is done entirely by environment variables:
 
-| Environment variable   | Default value | description                                                              |
-|------------------------|---------------|--------------------------------------------------------------------------|
-| `GITBOT_XMPP_JID`      | Mandatory     | Gitbot xmpp account full JID (user@host)                                 |
-| `GITBOT_XMPP_PASSWORD` | Mandatory     | Gitbot xmpp account password                                             |
-| `GITBOT_XMPP_MUC`      | Mandatory     | Full jib of target xmpp room (room@host)                                 |
-| `GITBOT_IP`            | `0.0.0.0`     | IP address on which the gitbot server is listening (to receive webwook)  |
-| `GITBOT_PORT`          | `8080`        | port number on which the gitbot server is listening (to receive webwook) |
-| `GITLAB_TOKEN`         | Mandatory     | The secret token that gitlab must use for the webhook                    |
+| Environment variable           | Default value | description                                                              |
+|--------------------------------|---------------|--------------------------------------------------------------------------|
+| `GITBOT_XMPP_JID`              | Mandatory     | Gitbot xmpp account full JID (user@host)                                 |
+| `GITBOT_XMPP_PASSWORD`         | Mandatory     | Gitbot xmpp account password                                             |
+| `GITBOT_XMPP_MUC`              | Mandatory     | Full jib of target xmpp room (room@host)                                 |
+| `GITBOT_IP`                    | `0.0.0.0`     | IP address on which the gitbot server is listening (to receive webwook)  |
+| `GITBOT_PORT`                  | `8080`        | port number on which the gitbot server is listening (to receive webwook) |
+| `GITLAB_TOKEN`                 | Mandatory     | The secret token that gitlab must use for the webhook                    |
+| `GITBOT_EXCLUDED_REPOSITORIES` | `""`          | List of git repositories that should not be tracked                      |
diff --git a/src/main.rs b/src/main.rs
index 9c84de858840ea63ef060223f2fa45eb1159bd4a..da706d964bf2b5602110f3cae75416ff7e19cd1f 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -2,6 +2,7 @@ use bytes::Bytes;
 use gitlab::webhooks::{IssueAction, MergeRequestAction, WebHook, WikiPageAction};
 use log::{info, warn};
 use std::{
+    collections::HashSet,
     net::{IpAddr, SocketAddr},
     str::FromStr,
 };
@@ -35,6 +36,9 @@ struct Opt {
     /// Gitlab token ("X-Gitlab-Token")
     #[structopt(short = "H", long = "header", env("GITLAB_TOKEN"))]
     gitlab_token: String,
+    /// List of git repositories that should not be tracked
+    #[structopt(short, long, env("GITBOT_EXCLUDED_REPOSITORIES"))]
+    excluded_repositories: Vec<String>,
 }
 
 #[tokio::main]
@@ -47,6 +51,7 @@ async fn main() -> anyhow::Result<()> {
     let ip = opt.ip;
     let port = opt.port;
     let gitlab_token = opt.gitlab_token;
+    let excluded_repositories = opt.excluded_repositories.into_iter().collect();
 
     pretty_env_logger::init();
 
@@ -64,11 +69,11 @@ async fn main() -> anyhow::Result<()> {
 
     // Functional logic: convert each received webhook to text message and send it to xmpp room
     while let Some(gitlab_web_hook) = receiver.recv().await {
-        if let Some(message) = webhook::format_webhook(&gitlab_web_hook) {
+        if let Some(message) = webhook::format_webhook(&excluded_repositories, &gitlab_web_hook) {
             info!("message: {}", message);
             xmpp_agent.send_message(&message, &muc_jid).await;
         } else {
-            warn!("Unhandled webhook payload: {:?}", gitlab_web_hook);
+            info!("Ignored webhook: {:?}", gitlab_web_hook);
         }
     }
 
diff --git a/src/webhook.rs b/src/webhook.rs
index 886519792aa100ec7983dc1608fac1596c435ee8..37e12b0be688c67c5b01ef1b2aaa4252cf39e80f 100644
--- a/src/webhook.rs
+++ b/src/webhook.rs
@@ -1,17 +1,19 @@
 use crate::*;
 
-pub(super) fn format_webhook(wh: &WebHook) -> Option<String> {
+pub(super) fn format_webhook(
+    excluded_repositories: &HashSet<String>,
+    wh: &WebHook,
+) -> Option<String> {
     log::debug!("receive webhook: {:?}", wh);
     Some(match wh {
         WebHook::Build(build) => {
-            println!("Build: {:?}", build);
+            info!("Build: {:?}", build);
             return None;
         }
         WebHook::Issue(issue) => {
-            // Error("invalid value: web hook, expected
-            // Error(\"invalid value: hook date, expected
-            // ParseError(Invalid)\", line: 0, column: 0)", line: 0,
-            // column: 0)
+            if excluded_repositories.contains(&issue.project.path_with_namespace) {
+                return None;
+            }
             let action = match issue.object_attributes.action {
                 Some(IssueAction::Update) => "updated",
                 Some(IssueAction::Open) => "opened",
@@ -35,6 +37,9 @@ pub(super) fn format_webhook(wh: &WebHook) -> Option<String> {
             )
         }
         WebHook::MergeRequest(merge_req) => {
+            if excluded_repositories.contains(&merge_req.project.path_with_namespace) {
+                return None;
+            }
             let action = match merge_req.object_attributes.action {
                 Some(MergeRequestAction::Approved) => "approved",
                 Some(MergeRequestAction::Update) => "updated",
@@ -61,14 +66,17 @@ pub(super) fn format_webhook(wh: &WebHook) -> Option<String> {
             )
         }
         WebHook::Note(note) => {
-            println!("Note: {:?}", note);
+            info!("Note: {:?}", note);
             return None;
         }
-        WebHook::Pipeline(_pipeline) => {
-            // TODO create text for pipeline
+        WebHook::Pipeline(pipeline) => {
+            info!("Pipeline: {:?}", pipeline);
             return None;
         }
         WebHook::Push(push) => {
+            if excluded_repositories.contains(&push.project.path_with_namespace) {
+                return None;
+            }
             let branch_name = if push.ref_.starts_with("refs/heads/") {
                 &push.ref_[11..]
             } else {
@@ -89,6 +97,9 @@ pub(super) fn format_webhook(wh: &WebHook) -> Option<String> {
             text
         }
         WebHook::WikiPage(page) => {
+            if excluded_repositories.contains(&page.project.path_with_namespace) {
+                return None;
+            }
             let action = match page.object_attributes.action {
                 WikiPageAction::Update => "updated",
                 WikiPageAction::Create => "created",